SECS/GEM之SECS Driver开发源代码

1 简介

1. Secs Driver 由金南瓜科技提供,适用于半导体、光伏、面板、PCB等行业

支持C、C++、C#等编程语言(C#对应C#DLL库)

2. SECS Driver集成E5,E37的功能。支持主动或者被动模式通讯,实时接收数据和反馈通讯状态给上层应用。

3. 用户可以按照客户的要求(Space)或自己的需求,进行设计SECS编码。SECS Driver提供编辑SECS编码的接口。

4. 接口使用简单,支持多线异步调用,无需用户考虑多线程问题。SECS Driver支持用户多线程交互使用。

5. 金南瓜已经集成HSMS的功能处理,超时处理、Message等待接收超时、重试连接等。

2 使用

2.1 C/C++版本

2.1.1 导入资料

将以下文件添加到项目当中

--> JngHightSpeedSecsExport.h

--> JngSecsEx.h

--> JngSecsEx.cpp

SECS/GEM之SECS Driver开发源代码_第1张图片

代码文件

依赖库DLL

依赖Lib

2.1.2 添加依赖项

依赖性如下图

JngHightSpeedSecs.lib

SECS/GEM之SECS Driver开发源代码_第2张图片

2.1.3 添加文件到项目

将.h和.cpp添加到项目中

3 使用SECS库

代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using 金南瓜;

namespace SecsExampleJngCNet
{
    public partial class MainForm : Form
    {
        JngSecsEx m_pSecs = new JngSecsEx();

        delegate void SetConnectState(SECS_STATE nState);
        delegate void SetShowMsg(string pText);
        SetConnectState m_pConnectState;
        SetShowMsg m_pMsgShow;
        OnAsyncMsgTimeoutHandle m_pAsyncMsgTimeoutHandle;

        public MainForm()
        {
            InitializeComponent();

            m_pConnectState = SetState;
            m_pMsgShow = ShowMsg; 
            m_pAsyncMsgTimeoutHandle = AsyncMsgTimeoutProc;
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            JS_SETTING setting;
            setting.nDeviceID = StringToNum.atoi(textDeviceID.Text);
            setting.nPort = StringToNum.atoi(textPort.Text);
            setting.nConnectMode = (checkPassive.Checked == true ? 1 : 0);
            setting.pIP = textIP.Text;
            setting.nT3 = 5000;
            setting.nT5 = 5000;
            setting.nT6 = 5000;
            setting.nT7 = 5000;
            setting.nT8 = 5000;
            
            m_pSecs.pMsgHandle = OnMyMsgProc;
            m_pSecs.pStateChangeHandle = OnMyStateProc;
            m_pSecs.pAsyncMsgTimeoutHandle = OnAsyncMsgTimeoutProc;

            if (m_pSecs.StartSecs(setting) == 0)
            {
                ShowMsg("开始通讯");
            }

        }

        private void button1_Click(object sender, EventArgs e)
        {
            int nTransaction = 0;
            JngDataEx pData = new JngDataEx();

            string x = "122323";
            pData.AddAscii(x.ToCharArray());
            
            m_pSecs.SendAsyncData(1, 1, true, ref nTransaction, pData);

            ShowMsg("\r\n异步消息ID:" + nTransaction.ToString() + "发送完成");
            ShowSML(1, 1, pData, true);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            int nTransaction = 0;
            JngDataEx pData = new JngDataEx();
            pData.AddList(0);
            ShowSML(1, 13, pData, true);

            m_pSecs.SendAsyncData(1, 13, true, ref nTransaction, pData);
                       
        }

        private void buttonS2F25_Click(object sender, EventArgs e)
        {
  //          byte [] pByte = new byte[3];
  //          pByte[0] = 0x12;
  //          pByte[1] = 0xF2;
  //          pByte[2] = 0x1D;
  //
  //          double [] dbF = new double[2];
  //          dbF[0] = 5.22;
  //          dbF[1] = -63.4;
  //
  //          int[] dbI = new int[2];
  //          dbI[0] = 5;
  //          dbI[1] = 630120124;
  //
  //          JngDataEx pData = new JngDataEx();
  //          pData.AddList(5);
  //          pData.AddBool(true);
  //          pData.AddBinary(pByte);
  //          pData.AddDouble(dbF);
  //          pData.AddAscii("1234");
  //          pData.AddInt(dbI);
            int nTransaction = 0;

            double[] dbF = new double[1];
            dbF[0] = 5.22;

            JngDataEx pData = new JngDataEx();
            pData.AddDouble(dbF);
            
            m_pSecs.SendAsyncData(2, 25, true, ref nTransaction, pData);

            ShowMsg("\r\n异步消息ID:" + nTransaction.ToString() + "发送完成");
            ShowSML(2, 25, pData, true);
            
        }


        // 响应数据回调
        public void OnMyStateProc(SECS_STATE nState, object pClientData)
        {
            BeginInvoke(m_pConnectState, nState);
        }

        void SetState(SECS_STATE nState)
        {
            
            switch (nState)
            {
                case SECS_STATE.eSecsStateListen: textBoxSecsState.Text = "等待连接"; break;
                case SECS_STATE.eSecsStateConnect: textBoxSecsState.Text = "建立连接"; break;
                case SECS_STATE.eSecsStateDisconnect: textBoxSecsState.Text = "断开连接"; break;
                case SECS_STATE.eSecsStateEnsureComm: textBoxSecsState.Text = "已建立通讯"; break;
            }

            ShowMsg( textBoxSecsState.Text + "\r\n");
        }

        // 异步消息等待接收超时
        public void OnAsyncMsgTimeoutProc(int nTransfer, object pClientData)
        {
            BeginInvoke(m_pAsyncMsgTimeoutHandle, nTransfer, pClientData);
        }

        void AsyncMsgTimeoutProc(int nTransfer, object pClientData)
        {
            ShowMsg("\r\n异步消息ID:" + nTransfer.ToString() + "超时");
        }


        string AppendIndent(long myIndentLevel)
        {
            string pTmp = "";

            for (int i = 0; i < myIndentLevel; i++)
            {
                pTmp += "  ";
            }

            return pTmp;
        }
        
        // 更新到界面   
        void ShowMsg(string pText)
        {                    
            textBoxrecv.Text += pText;
            textBoxrecv.Select(textBoxrecv.TextLength, 0);//光标定位到文本最后
            textBoxrecv.ScrollToCaret();//滚动到光标处
        }

        // 响应还在
        void OnHere(MESSGE_PARAM pPaeam)
        {
            JngDataEx pData = new JngDataEx();
            pData.AddList(0);           
            m_pSecs.SendReplyMessage(1, 2, pPaeam.nTransaction, ref pData);
        }

        // 响应数据回调
        public void OnMyMsgProc(MESSGE_PARAM pPaeam, JngDataEx pData, object pClientData)
        {
            int nStream = pPaeam.nStream;
            int nFunction = pPaeam.nFunction;

            if (nStream == 1 && nFunction == 1)
            {
                OnHere(pPaeam);
            }
            else if (pPaeam.nStream == 1 && pPaeam.nFunction == 13)
            {
                OnCommS1F13(pPaeam.nTransaction);
            }	

            ShowSML(nStream, nFunction, pData);
        }
        

        public void ShowSML(int nStream, int nFunction, JngDataEx pData, bool bSend = false)
        {
            SECS_TYPE nType = SECS_TYPE._ERR_TYPE;
            int nSize = 0;

            //
            // 显示数据            
            string pTmpData = "";
            long[] myStack = new long[128];
            long myStackPtr = 0;

            string pBegin;		// 前面添加的对象
            string pEnd;

            // 一个整体数据
            string pAllInfo;

            if (bSend)
            {
                pAllInfo = "\r\n发送数据:";
            }
            else
            {
                pAllInfo = "\r\n收到数据:";
            }
            pAllInfo += "S";
            pAllInfo += nStream.ToString();
            pAllInfo += "F"; 
            pAllInfo += nFunction.ToString();

            // 循环提取数据
            pData.MoveHead();
            while (true)
            {
                object pItemData = null;
                int nCode = pData.GetNextData(ref nType, ref nSize, ref pItemData);
                if (nCode != 0)
                {
                    string pErrTmp = "数据有误,错误代码:" + nCode.ToString();
                    break;
                }
                else
                {
                    // 对方发送的数据没有错误
                    if (pData.DataIsEnd())
                    {
                        break;
                        // 数据提取完成
                    }
                    else
                    {
                        // 字符控制
                        pBegin = "";
                        pEnd = "";

                        if (myStackPtr > 0)
                        {
                            if (myStack[myStackPtr - 1] > 0)
                            {
                                myStack[myStackPtr - 1]--;
                                pBegin = AppendIndent(myStackPtr);
                            }
                            else
                            {
                                myStackPtr--;
                                myStack[myStackPtr - 1]--;

                                pBegin = AppendIndent(myStackPtr);
                                pEnd = ">\r\n";
                            }
                        }


                        switch (nType)
                        {
                            case SECS_TYPE._LIST:
                                {
                                    pTmpData = "
            //   
            // >
            pData.AddList(2);
            pData.AddBinary(pBinary);
            pData.AddList(2);
            pData.AddAscii("jin nan gua ke ji");
            pData.AddAscii("1.0.4");
            ShowSML(1, 14, pData);

            m_pSecs.SendReplyMessage(1, 14, nTransaction, ref pData);

        }

    }
}




接口代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

///
// 广州金南瓜科技 SECS库
// 网站 http://www.semisecs.com
///

namespace 金南瓜
{     

    // SECS 数据类
    public class JngDataEx
    {
        IntPtr m_pJsData;
        int m_nPos;
        bool m_bDataEnd;

        public JngDataEx()
        {
            m_nPos = 0;
            m_pJsData = JngHightSpeedSecsExport.JS_CreateDataObject();
        }

        ~JngDataEx()
        {
            JngHightSpeedSecsExport.JS_DelereDataObject(m_pJsData);
        }
        
        // 添加单个指定数据
        public void AddList(int nSize)
        {
            JngHightSpeedSecsExport.JS_DataItemAddList(m_pJsData, nSize);
        }
        
        // ASCII字符串
        public void AddAscii(string pData)
        {
            IntPtr pAddr = Marshal.AllocHGlobal(pData.Length);
            try
            {
                byte[] pASCII = Encoding.ASCII.GetBytes(pData);
                Marshal.Copy(pASCII, 0, pAddr, pASCII.Length);
                JngHightSpeedSecsExport.JS_DataItemAdd(m_pJsData, (Int32)pData.Length, SECS_TYPE._ASCII, pAddr);
            }
            catch
            {
            }
            Marshal.FreeHGlobal(pAddr);
        }

        // ASCII字符串
        public void AddAscii(char[] pData)
        {
            IntPtr pAddr = Marshal.AllocHGlobal(pData.Length);
            try
            {
                byte[] pASCII = Encoding.ASCII.GetBytes(pData);
                Marshal.Copy(pASCII, 0, pAddr, pASCII.Length);
                JngHightSpeedSecsExport.JS_DataItemAdd(m_pJsData, (Int32)pData.Length, SECS_TYPE._ASCII, pAddr);
            }
            catch
            {
            }
            Marshal.FreeHGlobal(pAddr);
        }


        // 二进制
        public void AddBinary(byte[] pData)
        {
            IntPtr pAddr = Marshal.AllocHGlobal(pData.Length);
            try
            {
                Marshal.Copy(pData, 0, pAddr, pData.Length);
                JngHightSpeedSecsExport.JS_DataItemAdd(m_pJsData, (Int32)pData.Length, SECS_TYPE._BINARY, pAddr);
            }
            catch
            {
            }
            Marshal.FreeHGlobal(pAddr);
        }

        // 布尔类型
        public void AddBool(bool pData)
        {
            bool[] pTmp = new bool[1];
            pTmp[0] = pData;
            AddBool(pTmp);
        }

        // 布尔类型
        public void AddBool(bool[] pData)
        {
            IntPtr pAddr = Marshal.AllocHGlobal(pData.Length);
            try
            {
                byte[] pTmp = new byte[pData.Length];
                for (int i = 0; i < pData.Length; i++)
                {
                    pTmp[i] = (Byte)(pData[i] ? 1 : 0);
                }
                Marshal.Copy(pTmp, 0, pAddr, pTmp.Length);
                JngHightSpeedSecsExport.JS_DataItemAdd(m_pJsData, (Int32)pData.Length, SECS_TYPE._BOOLEAN, pAddr);
            }
            catch
            {
            }
            Marshal.FreeHGlobal(pAddr);
        }

        // 2字节整形
        public void AddInt(Int16 pData)
        {
            Int16[] pList = new Int16[1];
            pList[0] = pData;

            AddInt(pList);
        }

        public void AddInt(Int16[] pData)
        {
            JngHightSpeedSecsExport.JS_DataItemAddI2(m_pJsData, pData.Length, pData);
        }

      // 4字节整形
        public void AddInt(Int32 pData)
        {
            Int32[] pList = new Int32[1];
            pList[0] = pData;

            AddInt(pList);
        }
          
        public void AddInt(Int32[] pData)
        {
            JngHightSpeedSecsExport.JS_DataItemAddI4(m_pJsData, pData.Length, pData);
        }

        // 1字节无符号整形
        public void AddUInt(byte pData)
        {
            byte[] pList = new byte[1];
            pList[0] = pData;

            AddUInt(pList);
        }

        public void AddUInt(byte[] pData)
        {
            JngHightSpeedSecsExport.JS_DataItemAddU1(m_pJsData, pData.Length, pData);
        }

        // 2字节无符号整形
        public void AddUInt(UInt16 pData)
        {
            UInt16[] pList = new UInt16[1];
            pList[0] = pData;

            AddUInt(pList);
        }

        public void AddUInt(UInt16[] pData)
        {
            JngHightSpeedSecsExport.JS_DataItemAddU2(m_pJsData, pData.Length, pData);
        }
        
        // 4字节无符号整形
        public void AddUInt(UInt32 pData)
        {
            UInt32[] pList = new UInt32[1];
            pList[0] = pData;

            AddUInt(pList);
        }

        public void AddUInt(UInt32[] pData)
        {
            JngHightSpeedSecsExport.JS_DataItemAddU4(m_pJsData, pData.Length, pData);
        }

        // 浮点型
        public void AddFloat(float pData)
        {
            float[] pList = new float[1];
            pList[0] = pData;

            AddFloat(pList);
        }

        public void AddFloat(float[] pData)
        {
            int nSize = pData.Length * 4;
            IntPtr pAddr = Marshal.AllocHGlobal(nSize);
            try
            {
                Marshal.Copy(pData, 0, pAddr, pData.Length);
                JngHightSpeedSecsExport.JS_DataItemAdd(m_pJsData, (Int32)pData.Length, SECS_TYPE._F4, pAddr);
            }
            catch
            {
            }
            Marshal.FreeHGlobal(pAddr);
        }

        // 添加浮点型
        public void AddDouble(double pData)
        {
            double[] pList = new double[1];
            pList[0] = pData;

            AddDouble(pList);
        }

        public void AddDouble(double[] pData)
        {
            int nSize = pData.Length * 8;
            IntPtr pAddr = Marshal.AllocHGlobal(nSize);
            try
            {
                Marshal.Copy(pData, 0, pAddr, pData.Length);
                JngHightSpeedSecsExport.JS_DataItemAdd(m_pJsData, (Int32)pData.Length, SECS_TYPE._F8, pAddr);
            }
            catch
            {
            }
            Marshal.FreeHGlobal(pAddr);
        }

        //
        // 提取数据

        // 移动到数据开始
        public void MoveHead()
        {
            m_nPos = 0;
            m_bDataEnd = false;
        }

        // 数据是否已经读取完
        public bool DataIsEnd()
        {
            return m_bDataEnd;
        }

        // 下一个数据的长度、类型
        Int32 GetNextDataType(ref SECS_TYPE nType, ref Int32 nSize)
        {
            nSize = 0;
            nType = SECS_TYPE._ERR_TYPE;
            IntPtr pData = IntPtr.Zero;
            Int32 nPos = m_nPos;

            return JngHightSpeedSecsExport.JS_DataItemGetNext(m_pJsData, ref nType, ref nSize,
                ref pData, ref nPos);
        }

        // 值
        public Int32 GetNextData(ref SECS_TYPE nType, ref Int32 nSize, ref object pData)
        {
            Int32 nCode = 0;
            nSize = 0;
            nType = SECS_TYPE._ERR_TYPE;

            // 非托管
            IntPtr pBuffer = IntPtr.Zero;
            pData = null;
            try
            {
                // 获取数据
                int nPrePos = m_nPos;
                nCode = JngHightSpeedSecsExport.JS_DataItemGetNext(m_pJsData, ref nType, ref nSize, ref pBuffer, ref m_nPos);
                if (nCode == 0 ||
                    nCode == (int)SECS_MODULE_CODE.CODE_SECS_NO_MORE_DATA)
                {
                    if (nPrePos == m_nPos)
                    {
                        m_bDataEnd = true;
                        nCode = 0;
                    }
                    if (pBuffer != IntPtr.Zero)
                    {
                        pData = GetData(nType, ref nSize, pBuffer);
                    }
                }
            }
            catch (System.Exception)
            {
            }
            return nCode;
        }
       


        //
        // 内部使用接口

        // 内部使用接口
        public object GetData(SECS_TYPE nType, ref Int32 nSize, IntPtr pBuffer)
        {
            object pObject = null;

            switch (nType)
            {
                case SECS_TYPE._LIST: break;

                case SECS_TYPE._ASCII:
                    {
                        char[] pData = new char[nSize];
                        for (int i = 0; i < nSize; i++)
                        {
                            pData[i] = (char)Marshal.ReadByte(pBuffer, i);
                        }
                        pObject = pData;
                    }
                    break;

                case SECS_TYPE._BINARY:
                    {
                        byte[] pData = new byte[nSize];
                        Marshal.Copy(pBuffer, pData, 0, nSize);
                        pObject = pData;
                    }
                    break;

                case SECS_TYPE._BOOLEAN:
                    {
                        bool[] pData = new bool[nSize];
                        for (int i = 0; i < nSize; i++)
                        {
                            pData[i] = (Marshal.ReadByte(pBuffer, i) != 0);
                        }
                        pObject = pData;
                    }
                    break;

                case SECS_TYPE._I1:
                    {
                        Int32[] pData = new Int32[nSize];
                        byte[] pTmpData = new byte[nSize];
                        Marshal.Copy(pBuffer, pTmpData, 0, nSize);
                        for (int i = 0; i < nSize; i++)
                        {
                            UInt32 nTmpUx = (UInt32)pTmpData[i];
                            if ((nTmpUx & 0x80) == 0x80)
                            {
                                nTmpUx |= 0xFFFFFF00;
                            }
                            pData[i] = (Int32)nTmpUx;
                        }

                        pObject = pData;
                    }
                    break;

                case SECS_TYPE._I2:
                    {
                        Int16[] pData = new Int16[nSize];
                        Marshal.Copy(pBuffer, pData, 0, nSize);
                        pObject = pData;
                    }
                    break;

                case SECS_TYPE._I4:
                    {
                        Int32[] pData = new Int32[nSize];
                        Marshal.Copy(pBuffer, pData, 0, nSize);
                        pObject = pData;
                    }
                    break;

                case SECS_TYPE._U1:
                    {
                        byte[] pData = new byte[nSize];
                        Marshal.Copy(pBuffer, pData, 0, nSize);
                        pObject = pData;
                    }
                    break;

                case SECS_TYPE._U2:
                    {
                        UInt16[] pData = new UInt16[nSize];
                        for (int i = 0; i < nSize; i++)
                        {
                            pData[i] = (UInt16)Marshal.ReadInt16(pBuffer, i * 2);
                        }
                        pObject = pData;
                    }
                    break;

                case SECS_TYPE._U4:
                    {
                        UInt32[] pData = new UInt32[nSize];
                        for (int i = 0; i < nSize; i++)
                        {
                            pData[i] = (UInt32)Marshal.ReadInt32(pBuffer, i * 4);
                        }
                        pObject = pData;
                    }
                    break;

                case SECS_TYPE._F4:
                    {
                        float[] pData = new float[nSize];
                        Marshal.Copy(pBuffer, pData, 0, nSize);
                        pObject = pData;
                    }
                    break;

                case SECS_TYPE._F8:
                    {
                        double[] pData = new double[nSize];
                        Marshal.Copy(pBuffer, pData, 0, nSize);
                        pObject = pData;
                    }
                    break;
            }


            return pObject;
        }


        // 内部使用接口
        public JngDataEx(IntPtr pData)
        {
            m_nPos = 0;
            m_pJsData = pData;
        }

        // 获取数据,内部函数
        public IntPtr GetData()
        {
            return m_pJsData;
        }

        // 设置数据,内部函数
        public void SetData(IntPtr pJsData)
        {
            if (m_pJsData != IntPtr.Zero)
            {
                JngHightSpeedSecsExport.JS_DelereDataObject(m_pJsData);
            }
            m_pJsData = pJsData;
        }

        public void AddItem(int nSize, SECS_TYPE nType, object pData)
        {
            //           JngHightSpeedSecsExport.JS_DataItemAdd(m_pJsData, nSize, nType, ref pData);
        }

    }
}

SECS/GEM接口代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;


///
// 广州金南瓜科技 SECS库
// 网站 http://www.semisecs.com
///


namespace 金南瓜
{    
    // SECS 通讯操作类


    // 状态改变处理
    public delegate void OnStateChangeHandle(SECS_STATE nState, object pClientData);

    // 消息处理
    public delegate void OnMsgHandle(MESSGE_PARAM pPaeam, JngDataEx pData, object pClientData);

    // 异步消息等待接收超时
    public delegate void OnAsyncMsgTimeoutHandle(int nTransfer, object pClientData);
    
    // 连接处理
    public class JngSecsEx
    {
        public OnMsgHandle pMsgHandle = null;                           // 消息接收函数
        public OnStateChangeHandle pStateChangeHandle = null;           // 通讯状态改变函数
        public OnAsyncMsgTimeoutHandle pAsyncMsgTimeoutHandle = null;   // 异步消息等待接收超时
        public object m_pClient = null;                                 // 用于多线程关联的对象

        // 内部变量
        IntPtr m_pSecsComm;       
        Mutex m_syncLock = new Mutex();
        bool m_bStart = false;  // 是否开始了
        long m_nKey;     // 获取唯一key
 
        OnMsgProc m_pOnMsgProc = null;
        OnStateChangeProc m_pOnStateChangeProc = null;
        OnAsyncMsgTimeoutProc m_pOnAsyncMsgTimeoutProc = null;

        public JngSecsEx()
        {
            m_pSecsComm = JngHightSpeedSecsExport.JS_CreateCommObject();
            m_pOnMsgProc = new OnMsgProc(OnMyMsgProc);
            m_pOnStateChangeProc = new OnStateChangeProc(OnStateChangeHandle);
            m_pOnAsyncMsgTimeoutProc = new OnAsyncMsgTimeoutProc(OnAsyncMsgTimeoutHandle);

            // 获取唯一key        
            m_nKey = MapManage.Instance().AddObject(this);
        }

        ~JngSecsEx()
        {
            JngHightSpeedSecsExport.JS_SetCallback(m_pSecsComm, null, null, null, (IntPtr)0); 
            JngHightSpeedSecsExport.JS_ReleaseCommObject(m_pSecsComm);
            MapManage.Instance().DeleteObject(m_nKey);
        }

        // 开始通讯
        public int StartSecs(JS_SETTING setting)
        {
            int nCode = 0;
            m_syncLock.WaitOne();
            try
            {
                if (m_bStart == false)
                {
                    JngHightSpeedSecsExport.JS_SetCallback(m_pSecsComm, m_pOnMsgProc,
                        m_pOnStateChangeProc, m_pOnAsyncMsgTimeoutProc, (IntPtr)m_nKey);
                    nCode = JngHightSpeedSecsExport.JS_Start(m_pSecsComm, setting);
                    m_bStart = true;
                }
            }
            catch (System.Exception)
            {            	
            }
            m_syncLock.ReleaseMutex();
            return nCode;
        }
         
        // 停止通讯
        public void StopSecs()
        {
            m_syncLock.WaitOne();
            try
            {
                // 锁
                JngHightSpeedSecsExport.JS_ReleaseCommObject(m_pSecsComm);
                m_pSecsComm = JngHightSpeedSecsExport.JS_CreateCommObject();
                m_bStart = false;
            }
            catch (System.Exception)
            {
            }
            m_syncLock.ReleaseMutex();
        }
              
        /* 异步消息发送 */
        public int SendAsyncData(int nStream, int nFunction, bool bNeedReply, ref int nTransaction, JngDataEx pData = null)
        {
            MESSGE_PARAM param = new MESSGE_PARAM();
            param.nStream = nStream;
            param.nFunction = nFunction;
            param.nNeedReply = bNeedReply ? 1 : 0;

            if (pData == null)
            {
                pData = new JngDataEx();
            }

            int nCode = JngHightSpeedSecsExport.JS_SendAsyncMessage(m_pSecsComm, ref param, pData.GetData());
            nTransaction = param.nTransaction;

            return nCode;
        }

        /* 同步发送 */
        public int SendSyncData(int nStream, int nFunction, bool bNeedReply, JngDataEx pData,
            ref int nReplyStream, ref int nReplyFunction, ref JngDataEx pReplyData)
        {
            int nTransaction = 0;
            int nReplyTransaction = 0;

            return SendSyncData(nStream, nFunction, bNeedReply, ref nTransaction, pData,
                ref nReplyStream, ref nReplyFunction, ref nReplyTransaction, ref pReplyData);
        }


        /* 同步发送 */
        public int SendSyncData(int nStream, int nFunction, bool bNeedReply, ref int nTransaction, JngDataEx pData,
            ref int nReplyStream, ref int nReplyFunction, ref int nReplyTransaction, ref JngDataEx pReplyData)
        {
            MESSGE_PARAM param = new MESSGE_PARAM();
            param.nStream = nStream;
            param.nFunction = nFunction;
            param.nNeedReply = bNeedReply ? 1 : 0;
            
            // 答复数据
            MESSGE_PARAM replyParam = new MESSGE_PARAM();
            IntPtr pReplyPoint = new IntPtr();

            int nCode = JngHightSpeedSecsExport.JS_SendSyncMessage(m_pSecsComm, ref param, pData.GetData(), ref replyParam, ref pReplyPoint);
            nTransaction = param.nTransaction;

            // 返回值
            pReplyData = new JngDataEx(pReplyPoint);
            nReplyStream = replyParam.nStream;
            nReplyFunction = replyParam.nFunction;
            nReplyTransaction = replyParam.nTransaction;

            return nCode;
        }

        /* 答复消息发送 */
        public int SendReplyMessage(int nStream, int nFunction, int nTransaction, ref JngDataEx pData)
        {
            MESSGE_PARAM param = new MESSGE_PARAM();
            param.nStream = nStream;
            param.nFunction = nFunction;
            param.nTransaction = nTransaction;

            return JngHightSpeedSecsExport.JS_SendReplyMessage(m_pSecsComm, param, pData.GetData());
        }

        /* 答复消息发送 */
        public int SendReplyMessage(int nStream, int nFunction, int nTransaction)
        {
            JngDataEx pData = new JngDataEx();
            MESSGE_PARAM param = new MESSGE_PARAM();
            param.nStream = nStream;
            param.nFunction = nFunction;
            param.nTransaction = nTransaction;

            return JngHightSpeedSecsExport.JS_SendReplyMessage(m_pSecsComm, param, pData.GetData());
        }

        // 响应数据回调
        void OnMyMsgProc(IntPtr pComm, MESSGE_PARAM pPaeam, IntPtr pData, IntPtr pClientData)
        {
            JngSecsEx pSecs = MapManage.Instance().GetObject((long)pClientData);

            if (pSecs != null) 
            {
                try
                {
                    if (pSecs.pMsgHandle != null)
                    {
                        JngDataEx SecsData = new JngDataEx(pData);
                        pSecs.pMsgHandle(pPaeam, SecsData, m_pClient);
                    }
                }
                catch (Exception )
                {
                   
                }
            }
        }

        // 响应状态回调
        void OnStateChangeHandle(IntPtr pComm, Int32 nState, IntPtr pClientData)
        {
            JngSecsEx pSecs = MapManage.Instance().GetObject((long)pClientData);
            if (pSecs != null)
            {
                try
                {
                    if (pSecs.pStateChangeHandle != null)
                    {
                        pSecs.pStateChangeHandle((SECS_STATE)nState, m_pClient);
                    }
                }
                catch
                {
                }
            }
        }

        // 异步消息等待接收超时
        void OnAsyncMsgTimeoutHandle(IntPtr pComm, Int32 nTransfer, IntPtr pClientData)
        {
            JngSecsEx pSecs = MapManage.Instance().GetObject((long)pClientData);
            if (pSecs != null)
            {
                try
                {
                    if (pSecs.pAsyncMsgTimeoutHandle != null)
                    {
                        pSecs.pAsyncMsgTimeoutHandle(nTransfer, m_pClient);
                    }
                }
                catch
                {
                }
            }
        }  
    }
}

代码 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace 金南瓜
{
    // SECS的数据格式清单
    public enum SECS_TYPE
    { 
        _ERR_TYPE       = 0x00,
        _LIST            = 0x01,
        _BINARY            = 0x02,
        _BOOLEAN        = 0x03,
        _ASCII            = 0x04,
        _I1                = 0x10,                 /* C#没有8位的有符号整形,建立使用Int16、Int32代替 */
        _I2                = 0x11,
        _I4                = 0x12,
        _I8                = 0x13,
        _F8                = 0x20,
        _F4                = 0x21,
        _U1                = 0x30,
        _U2                = 0x31,
        _U4                = 0x32,
        _U8                = 0x33,
    }
        
    public enum SECS_MODULE_CODE
    {
        SUCC                         = 0,    /* 成功 */
        CODE_POINT_IS_NULL             = 100,    /* 指针地址为空 */
        CODE_SECS_DATA_ERROR         = 101,    /* SECS数据错误 */
        CODE_SECS_DATA_SIZE_ERROR     = 102,    /* SECS数据长度不匹配错误 */
        CODE_SECS_NO_MORE_DATA       = 103, /* 没有更多的数据了 */
    }

    public enum SECS_STATE
    {
        eSecsStateDisconnect = 1,        // 断开连接
        eSecsStateListen = 2,            // 倾听、等待通讯
        eSecsStateConnect = 3,            // 建立连接成功
        eSecsStateEnsureComm = 4,        // 确认通讯成功
    };
     
    // 参数
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct JS_SETTING      
    {
        public Int32 nT3;                        // 等待答复超时,单位毫秒(Reply timeout)
        public Int32 nT5;                        // 重连超时,单位毫秒(Connect separation timeout)
        public Int32 nT6;                        // 控制交换信息超时,单位毫秒(Control transaction timeout)
        public Int32 nT7;                        // 确认选中超时,单位毫秒(Not selected timeout)
        public Int32 nT8;                        // 网络字节超时,单位毫秒(Network intercharacter timeout)
        public Int32 nConnectMode;                // 1=Passive, 0=Active    
        public Int32 nPort;                     // 网络端口号
        public Int32 nDeviceID;                 // 设备ID
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)]
        public string pIP;                        // a string IP "103.214.16.101"     
    };

    
    // 发送消息数据
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct MESSGE_PARAM        
    {
        public Int32 nStream;
        public Int32 nFunction;
        public Int32 nNeedReply;        // 0:不需要答复, 1:需要答复
        public Int32 nTransaction;        // 主动发送时候为空 
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
        public Byte[] pHeader;            
    };


    
    // 托管也使用cdecl方式
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    public delegate void OnMsgProc(IntPtr pComm, MESSGE_PARAM pPaeam, IntPtr pData, IntPtr pClientData);
    
    // 连接处理
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    public delegate void OnStateChangeProc(IntPtr pComm, Int32 nState, IntPtr pClientData);

    // 异步消息等待接收超时
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    public delegate void OnAsyncMsgTimeoutProc(IntPtr pComm, Int32 nTransfer, IntPtr pClientData);

    class JngHightSpeedSecsExport
    {
         
        /* 创建通讯对象 */
        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public IntPtr JS_CreateCommObject();
        
        /* 断开一个连接(如果需要断开连接)和释放资源 */
        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_ReleaseCommObject(IntPtr pHandle);

        /* 开始通讯 */
        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public Int32 JS_Start(IntPtr pHandle, JS_SETTING setting);

        /* 回调函数,通讯之前设置 */
        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public Int32 JS_SetCallback(IntPtr pHandle, OnMsgProc pMsgProc,
            OnStateChangeProc pStateChangeProc, OnAsyncMsgTimeoutProc pAsyncMsgTimeoutProc, IntPtr pClient);

// 数据发送

        /* 异步消息发送 */
        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public Int32 JS_SendAsyncMessage(IntPtr pHandle, ref MESSGE_PARAM param, IntPtr pData);

        /* 同步消息发送, 返回数据需要JS_DelereObject释放 */
        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public Int32 JS_SendSyncMessage(IntPtr pHandle, ref MESSGE_PARAM param, IntPtr pData, ref MESSGE_PARAM replyParam, ref IntPtr pReplyData);
          
        /* 答复消息发送 */
        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public Int32 JS_SendReplyMessage(IntPtr pHandle, MESSGE_PARAM param, IntPtr pData);
    

// 数据操作
        
        /* 创建顺序对象 */
        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public IntPtr JS_CreateDataObject();

        /* 删除顺序对象 */
        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DelereDataObject(IntPtr pObject);
        
        /* 添加数据 */
        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAdd(IntPtr pObject, Int32 nSize, SECS_TYPE nType, IntPtr pData);
       
        /* 获取数据 */
        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public Int32 JS_DataItemGetNext(IntPtr pObject, ref SECS_TYPE nType,
            ref Int32 nSize, ref IntPtr pData, ref Int32 nPos);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public Int32 JS_DataItemGetNextData(IntPtr pObject, SECS_TYPE nType,
            Int32 nSize, IntPtr pData, ref Int32 nPos);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddList(IntPtr pObject, Int32 nSize);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddBriny(IntPtr pObject, Int32 nSize, ref byte[] pData);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddBool(IntPtr pObject, Int32 nSize, ref bool[] pData);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddAscii(IntPtr pObject, Int32 nSize, ref string pData);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddI1(IntPtr pObject, Int32 nSize, ref byte[] pData);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddI2(IntPtr pObject, Int32 nSize, Int16[] pData);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddI4(IntPtr pObject, Int32 nSize, Int32[] pData);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddI8(IntPtr pObject, Int32 nSize, ref Int64[] pData);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddU1(IntPtr pObject, Int32 nSize, byte[] pData);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddU2(IntPtr pObject, Int32 nSize, UInt16[] pData);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddU4(IntPtr pObject, Int32 nSize, UInt32[] pData);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddU8(IntPtr pObject, Int32 nSize, ref UInt64[] pData);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddDouble4(IntPtr pObject, Int32 nSize, ref float[] pData);

        [DllImport("JngHightSpeedSecs", CallingConvention = CallingConvention.StdCall)]
        extern static public void JS_DataItemAddDouble8(IntPtr pObject, Int32 nSize, ref double[] pData);
   
    
    
    
    
    
    }  


}
 

你可能感兴趣的:(SECS,SECS/GEM,GEM,半导体,SECS,DRIVER)