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; }