发表于:2011-05-16 21:51:48
5楼
在VC中使用DLL一般都是采用动态声明的方式,函数说明中给出的是Delphi的函数原型,
在VC中声明时只要注意一下类型的对应即可,Delphi中的longint类型对应VC中的int类型
Delphi中的Pchar对应VC中的char* ,下面给出主要函数的声明:
在使用的文件的cpp中声明一个句柄:
HINSTANCE hinstDLL;
用来标识导入的动态链接库。
1)、按下例说明声明相关各个函数:(在cpp文件的头处声明)
typedef int (_stdcall *pOpen)(int nport, int BaudRate, int DataBits, char* Parity, int StopBits, char* User);
typedef int (_stdcall *pClose)(int nport);
typedef int (_stdcall *pSetDelay)(int nport);
typedef int (_stdcall *pComTrue)(int nport);
typedef int (_stdcall *pComWork)(int nport);
typedef int (_stdcall *pfcn01)(int nport, int node, int address, int Count,int* RxdBuffer);
typedef int (_stdcall *pfcn02)(int nport, int node, int address, int Count,int* RxdBuffer);
typedef int (_stdcall *pfcn03)(int nport, int node, int address, int Count,int* RxdBuffer);
typedef int (_stdcall *pfcn04)(int nport, int node, int address, int Count,int* RxdBuffer);
typedef int (_stdcall *pfcn05)(int nport, int node, int address, int value);
typedef int (_stdcall *pfcn06)(int nport, int node, int address, int value);
typedef int (_stdcall *pfcn15)(int nport, int node, int address, int Count,int* TxdBuffer);
typedef int (_stdcall *pfcn16)(int nport, int node, int address, int Count,int* TxdBuffer);
typedef int (_stdcall *pfcn03DInt)(int nport, int node, int regular, int address, int Count,int* RxdBuffer);
typedef int (_stdcall *pfcn03Float)(int nport, int node, int regular, int address, int Count,float* RxdBuffer);
typedef int (_stdcall *pfcn04DInt)(int nport, int node, int regular, int address, int Count,int* RxdBuffer);
typedef int (_stdcall *pfcn04Float)(int nport, int node, int regular, int address, int Count,float* RxdBuffer);
typedef int (_stdcall *pfcn16DInt)(int nport, int node, int regular, int address, int Count,int* TxdBuffer);
typedef int (_stdcall *pfcn16Float)(int nport, int node, int regular, int address, int Count,float* TxdBuffer);
typedef int (_stdcall *pWbitWrite)(int nport, int node, int address, int Bit, int value);
typedef int (_stdcall *pWbitSetReset)(int nport, int node, int address, int Bit);
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文件的头处声明)
pOpen mOpen;
pClose mClose;
pSetDelay mSetDelay;
pComTrue mComTrue;
pComWork mComWork;
pfcn01 mfcn01;
pfcn02 mfcn02;
pfcn03 mfcn03;
pfcn04 mfcn04;
pfcn05 mfcn05;
pfcn06 mfcn06;
pfcn15 mfcn15;
pfcn16 mfcn16;
pfcn03DInt mfcn03DInt;
pfcn03Float mfcn03Float;
pfcn04DInt mfcn04DInt;
pfcn04Float mfcn04Float;
pfcn16DInt mfcn16DInt;
pfcn16Float mfcn16Float;
pWbitWrite mWbitWrite;
pWbitSetReset mWbitSetReset;
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("modbus_rtu.dll");
4)、判断dll文件是否存在并声明并建立动态链接库中的函数与新函数名的对应关系,
如下:(在cpp文件的OnInitDialog过程建立):
if (hinstDLL)
{
mOpen = (pOpen)GetProcAddress (hinstDLL,"mbrtuComOpen");
mClose = (pClose)GetProcAddress (hinstDLL,"mbrtuComClose");
mSetDelay = (pSetDelay)GetProcAddress (hinstDLL,"mbrtuSetDelay");
mComTrue = (pComTrue)GetProcAddress (hinstDLL,"mbrtuComTrue");
mComWork = (pComWork)GetProcAddress (hinstDLL,"mbrtuComWork");
mfcn01 = (pfcn01)GetProcAddress (hinstDLL,"mbrtufcn01");
mfcn02 = (pfcn02)GetProcAddress (hinstDLL,"mbrtufcn02");
mfcn03 = (pfcn03)GetProcAddress (hinstDLL,"mbrtufcn03");
mfcn04 = (pfcn04)GetProcAddress (hinstDLL,"mbrtufcn04");
mfcn05 = (pfcn05)GetProcAddress (hinstDLL,"mbrtufcn05");
mfcn06 = (pfcn06)GetProcAddress (hinstDLL,"mbrtufcn06");
mfcn15 = (pfcn15)GetProcAddress (hinstDLL,"mbrtufcn15");
mfcn16 = (pfcn16)GetProcAddress (hinstDLL,"mbrtufcn16");
mfcn03DInt = (pfcn03DInt)GetProcAddress (hinstDLL,"mbrtufcn03DInt");
mfcn03Float = (pfcn03Float)GetProcAddress (hinstDLL,"mbrtufcn03Float");
mfcn04DInt = (pfcn04DInt)GetProcAddress (hinstDLL,"mbrtufcn04DInt");
mfcn04Float = (pfcn04Float)GetProcAddress (hinstDLL,"mbrtufcn04Float");
mfcn16DInt = (pfcn16DInt)GetProcAddress (hinstDLL,"mbrtufcn16DInt");
mfcn16Float = (pfcn16Float)GetProcAddress (hinstDLL,"mbrtufcn16Float");
mWbitWrite = (pWbitWrite)GetProcAddress (hinstDLL,"mbrtuWordBitWrite");
mWbitSetReset = (pWbitSetReset)GetProcAddress (hinstDLL,"mbrtuWordBitSetReset");
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("modbus_rtu.dll已成功载入!");
}
else
{
AfxMessageBox("没找到modbus_rtu.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 = mComTrue(mnport);
if (k==1)
{
mClose(mnport);
}
FreeLibrary(hinstDLL);
}