modtcpslave.dll V1.0 施耐德modbus tcp协议(modbus plus网络),上位机从站模式
(modbus tcp服务器)通讯动态链接库DLL(以下简称DLL),是为满足工业通信需要,
针对工业领域要求上位机对PLC、工业仪表通讯实时采集与控制的组态编程而设计。
本DLL是采用Delphi语言开发的标准串口通讯库,具有以下特点:
1)、遵循modbus tcp(modbus plus网络)协议,DLL作为从站模式;
2)、支持多网络并发操作,支持多线程网络通讯,最多支持15个客户端连接
3)、实时性、可靠性好,通用性强;
4)、函数接口功能全,操作简单,支持modbus
tcp主要通信功能码;
5)、支持多种操作系统win9x/win2000/winXP(标准Win32 DLL);
6)、易于快速开发(VC等非RAD开发环境的开发);
7)、采用数组调用数据发送与接收,初学者快速入门;
8)、可在多种编程环境下使用,例如VB、VC、Delphi、PB、Labview、VB.net、C#、易语言等开发环境;
9)、扩展了函数功能读取下位机中的双字、单精度浮点等类型数据,更加符合工业自动化领域的工控软件的开发。
软件版本更新及相关说明:
modtcpslave.dll V1.0 施耐德modbus tcp协议(modbus plus网络)通讯链接库,实现了对保持寄存器
40001~4XXXX区数据读写(FCN03:读、 FCN16:写;FCN06写单个数据);
对逻辑线圈00001~0XXXX的读写(FCN01:读取一组线圈,FCN05:强置单线圈,FCN15强置多线圈);
对输入状态10001~1XXXX的读(FCN02);对输入寄存器30001~3XXXX的读(FCN04)。
在VC中使用DLL一般都是采用动态声明的方式,函数说明中给出的是Delphi的函数原型,
在VC中声明时只要注意一下类型的对应即可,Delphi中的longint类型对应VC中的int类型
Delphi中的Pchar对应VC中的char* ,下面给出主要函数的声明:
在使用的文件的cpp中声明一个句柄:
HINSTANCE hinstDLL;
用来标识导入的动态链接库。
1)、按下例说明声明相关各个函数:(在调用函数界面窗体cpp文件的头处声明)
//服务控制函数
typedef int (_stdcall *ptcpOpen)(int IpPort, char* User);
typedef int (_stdcall *ptcpClose)();
typedef int (_stdcall
*ptcpConnect)();
//读取从站元件值
typedef int (_stdcall *ptcpRr0X)(int address, int Count, int*
RxdBuffer);
typedef int (_stdcall *ptcpRr1X)(int address, int Count, int*
RxdBuffer);
typedef int (_stdcall *ptcpRr3X)(int address, int Count, int*
RxdBuffer);
typedef int (_stdcall *ptcpRr4X)(int address, int Count, int*
RxdBuffer);
//写入从站元件值
typedef int (_stdcall *ptcpWr0X)(int address, int Count, int*
TxdBuffer);
typedef int (_stdcall *ptcpWr1X)(int address, int Count, int*
TxdBuffer);
typedef int (_stdcall *ptcpWr3X)(int address, int Count, int*
TxdBuffer);
typedef int (_stdcall *ptcpWr4X)(int address, int Count, int*
TxdBuffer);
//适用拓展函数
typedef int (_stdcall *pBitBin)(int value, int
Bitaddress);
typedef int (_stdcall *p32I_16h)(int value);
typedef int
(_stdcall *p32I_16l)(int value);
typedef int (_stdcall *p16I_32I)(int valueH,
int valueL);
typedef int (_stdcall *p32f_16h)(float value);
typedef int
(_stdcall *p32f_16l)(float value);
typedef float (_stdcall *p16I_32f)(int
valueH, int valueL);
2)、建立动态链接库的新函数名:(在调用函数界面窗体cpp文件的头处声明)
ptcpOpen mtcpOpen;
ptcpClose mtcpClose;
ptcpConnect
mtcpConnect;
ptcpRr0X mtcpRr0X;
ptcpRr1X mtcpRr1X;
ptcpRr3X
mtcpRr3X;
ptcpRr4X mtcpRr4X;
ptcpWr0X mtcpWr0X;
ptcpWr1X mtcpWr1X;
ptcpWr3X
mtcpWr3X;
ptcpWr4X mtcpWr4X;
pBitBin mBitBin;
p32I_16h m32I_16h;
p32I_16l m32I_16l;
p16I_32I
m16I_32I;
p32f_16h m32f_16h;
p32f_16l m32f_16l;
p16I_32f
m16I_32f;
3)、导入动态链接库,如例所示:(在在调用函数界面窗体cpp文件的OnInitDialog过程建立):
hinstDLL = LoadLibrary("modtcpslave.dll");
4)、判断dll文件是否存在并声明并建立动态链接库中的函数与新函数名的对应关系,
如下:(在cpp文件的OnInitDialog过程建立):
if (hinstDLL)
{
mtcpOpen = (ptcpOpen)GetProcAddress
(hinstDLL,"tcpOpen");
mtcpClose = (ptcpClose)GetProcAddress
(hinstDLL,"tcpClose");
mtcpConnect = (ptcpConnect)GetProcAddress
(hinstDLL,"tcpConnect");
mtcpRr0X = (ptcpRr0X)GetProcAddress
(hinstDLL,"tcpRr0X");
mtcpRr1X = (ptcpRr1X)GetProcAddress
(hinstDLL,"tcpRr1X");
mtcpRr3X = (ptcpRr3X)GetProcAddress
(hinstDLL,"tcpRr3X");
mtcpRr4X = (ptcpRr4X)GetProcAddress
(hinstDLL,"tcpRr4X");
mtcpWr0X = (ptcpWr0X)GetProcAddress (hinstDLL,"tcpWr0X");
mtcpWr1X
= (ptcpWr1X)GetProcAddress (hinstDLL,"tcpWr1X");
mtcpWr3X =
(ptcpWr3X)GetProcAddress (hinstDLL,"tcpWr3X");
mtcpWr4X =
(ptcpWr4X)GetProcAddress (hinstDLL,"tcpWr4X");
mBitBin =
(pBitBin)GetProcAddress (hinstDLL,"DecBitBin");
m32I_16h =
(p32I_16h)GetProcAddress (hinstDLL,"Int32ToInt_16h");
m32I_16l =
(p32I_16l)GetProcAddress (hinstDLL,"Int32ToInt_16l");
m16I_32I=
(p16I_32I)GetProcAddress (hinstDLL,"Int16ToInt32");
m32f_16h =
(p32f_16h)GetProcAddress (hinstDLL,"Float32ToInt_16h");
m32f_16l =
(p32f_16l)GetProcAddress (hinstDLL,"Float32ToInt_16l");
m16I_32f=
(p16I_32f)GetProcAddress (hinstDLL,"Int16ToFloat32");
AfxMessageBox("modtcpslave.dll已成功载入!");
}
else
{
AfxMessageBox("没找到modtcpslave.dll!");
SendMessage(WM_CLOSE);
}
注:双引号中为动态链接库中的原有函数名。
函数中用到了char*型参数,这里介绍下char*与Cstring的相互转换的函数:
(1)char*->CString
char* sz;
CString str;
str.Format("%s",sz); //可以用此函数将读取的值转成字符串
(2) CString -> char*
CString str;
char* sz = str.GetBuffer(0);//可将字符串转成char*给函数赋值
5)、当不再需要使用DLL时记得关闭网络服务及释放动态链接库,(在OnDestroy事件中释放)
if(hinstDLL)
{
int k = mtcpConnect();
if (k==1)
{
mtcpClose();
}
FreeLibrary(hinstDLL);
}