2 imisspassword Imisspassword 于 2016.09.07 11:06 提问

VC和BCB编写DLL。 DWORD WINAPI 怪问题

函数原型是:DWORD (WINAPI* m_pfnGetInfo)(int nInfo, void* pBuf);
2个动态库,原来用BCB写的,没问题,
C++ BULIDER中这样:
extern "C" __declspec(dllexport) DWORD WINAPI GetInfo(int nInfo,void * pBuf)
VC2008,同样写
extern "C" __declspec(dllexport) DWORD WINAPI GetInfo(int nInfo,void * pBuf)
结果是GetProcAddress返回空,
改成这样:
extern "C" __declspec(dllexport) DWORD GetInfo(int nInfo,void * pBuf)
GetProcAddress返回正常,但调用时出错,信息为:Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
百思不得其姐!

3个回答

wlj1234
wlj1234   2016.09.07 12:11

没用过BCB,只知道这两个编译器生成的函数参数出入栈顺序不一致。
所以WINAPI这个宏要重新定义一下,VC中WINAPI默认__stdcall

出错原因是调用者实际调用是下面的函数
extern "C" __declspec(dllimport) DWORD GetInfo(void * pBuf,int nInfo)

GetProcAddress返回空,应该也是这个问题

hijack00
hijack00   Rxr 2016.09.07 12:34

出错信息说的很清楚了,是调用约定(calling convention)的问题,WINAPI是__stdcall方式,而C中默认是__cdecl,这两种方式有很大的区别,具体细节可以自行百度

Imisspassword
Imisspassword   2016.09.07 12:38

搞定了,原来是这样,如果VC中这样写extern "C" __declspec(dllexport) DWORD WINAPI GetInfo(int nInfo,void * pBuf),则产生的动态库对应函数前面会加下划线,
GetInfo变成了_GetInfo, 这样在GetProcAddress时就返回空了,
VC中要把定义写到DEF文件中,函数这样写DWORD WINAPI GetInfo(int nInfo,void * pBuf), 编译出来的动态库在调用时就没问题了。

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!