C++调用delphi的dll
在开发时需要用到股票数据,坑爹的数据商只提供给我们一个dll,一个txt说明文档,现在只知道dll是delphi写的 ,由于对delphi完全不熟悉,在查阅了一些资料后,我们决定使用C++去调用delphi dll的函数来获取股票数据,步骤也很简单。
声明函数类型
首先需要定义一个指针函数类型,这个类型必须和dll中函数类型和参数完全一致,比如:
typedef void (__stdcall *SetCallback)(
bool TOnGetMemProc(int*, int),
bool TOnFreeMemProc(int*),
void TOnFYSingleMarInit(PMarket),
void TOnFYRealStockData(unsigned int,PFYStockRealData),
void TOnFYEngineError(byte,unsigned short, char*));
C语言函数声明,举其中一个例子: void TOnFYRealStockData(unsigned int,PFYStockRealData);unsigned int对应delphi中的WORD,即无符号2字节整数,C中的PFYStockRealData是与delphi对应的一个结构体,它们的成员也必须完全一致。
动态载入dll
这里需要用到一个Windows API函数,LoadLibrary,它的作用是将dll映射到内存,并且返回句柄,载入指定的动态链接库,并将它映射到当前进程使用的地址空间,一旦载入,即可访问库内保存的资源。当不需要时,可以用FreeLibrary函数释放dll,因此才这种方式才被称为动态调用吧。
HMODULE hMod = LoadLibrary("XXXXXX.dll");
获取函数地址
第二个用到的Windows API函数,GetProcAddress,它的作用是返回函数指针,注意一定要先进行正确的类型转换, 不然调用会失败。
if (hMod)
{
SetCallback setCallback = (SetCallback)GetProcAddress(hMod,"SetCallback");
}
编译好的dll在运用的时候都会映射到内存中去,因此通过GetProcAddress函数,我们找到了需要调用函数的地址,而且我们也知道调用形式,然后就可以当作一个普通函数一样正常使用了。
一个完整的简单例子
不能运行,仅供参考
#include "stdafx.h"
bool TOnGetMemProc(int*, int) ;
bool TOnFreeMemProc(int*);
void TOnFYSingleMarInit(PMarket);
void TOnFYRealStockData(unsigned int,PFYStockRealData);
void TOnFYEngineError(byte,unsigned short, char*);
typedef int (__stdcall *SetCommInfo)(LPSTR aServ,
int aServPort,
LPSTR aUser,
LPSTR aPWD);
typedef int (__stdcall *StartDLL)();
typedef int (__stdcall *StopDLL)();
typedef void (__stdcall *SetCallback)(
bool TOnGetMemProc(int*, int),
bool TOnFreeMemProc(int*),
void TOnFYSingleMarInit(PMarket),
void TOnFYRealStockData(unsigned int,PFYStockRealData),
void TOnFYEngineError(byte,unsigned short, char*));
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hMod = LoadLibrary("XXXXXX.dll");
if (hMod)
{
SetCommInfo setCommInfo = (SetCommInfo)GetProcAddress(hMod,"SetCommInfo");
StartDLL startDLL = (StartDLL)GetProcAddress(hMod,"StartDLL");
StopDLL stopDLL = (StopDLL)GetProcAddress(hMod,"StopDLL");
SetCallback setCallback = (SetCallback)GetProcAddress(hMod,"SetCallback");
bool (*f1)(int*, int);
bool (*f2)(int*);
void (*f3)(PMarket);
void (*f4)(unsigned int,PFYStockRealData);
void (*f5)(byte, unsigned short, char*);
f1 = TOnGetMemProc;
f2 = TOnFreeMemProc;
f3 = TOnFYSingleMarInit;
f4 = TOnFYRealStockData;
f5 = TOnFYEngineError;
setCallback(f1,f2,f3,f4,f5);
}
return 0;
}