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等待接收超时、重试连接等。
将以下文件添加到项目当中
--> JngHightSpeedSecsExport.h
--> JngSecsEx.h
--> JngSecsEx.cpp
代码文件
依赖库DLL
依赖Lib
依赖性如下图
JngHightSpeedSecs.lib
将.h和.cpp添加到项目中
代码
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);
}
}