shikailun的日志

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;
}
Posted on
This entry was posted in technology  and tagged cpp