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币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
BCB多线程入门
1、创建一个线程执行的函数DWORD WINAPI ThreadFunc(LPVOID lpParameter):DWORD WINAPI ThreadFunc(LPVOID lpParameter){    int i;    TForm1 *pForm;    pForm = (TForm1*)lpParameter;    for (i=0;i    {        pForm->La
APIENTRY和WINAPI的区别
winapi表示此函数是普通的winapi函数调用方式,apientry则表明此函数是应用程序的入口点,相当于c的main()函数其实都是__stdcall   
DWORD WINAPI
DWORD WINAPI Zhaa(LPVOID PP) 查看WINAPI的定义,它是这样定义的 #define WINAPI _stdcall 可以发现CALLBACK也是这样定义的 _stdcall规定了编译时的一些选项WINAPI是一个宏,所代表的符号是__stdcall, 函数名前加上这个符号表示这个函数的调用约定是标准调用约定,windows API函数采用这种调用约定。
BCB编写DLL终极手册(写给新手)
BCB编写DLL终极手册 一. 编写 DLL File/New/Dll 生成 Dll 的向导,然后可以添加导出函数和导出类 导出函数:extern "C" __declspec(dllexport) ExportType FunctionName(Parameter) 导出类:class __declspec(dllexport) ExportType ClassName{...} 例子:(说明
简单的多线程编程_同步与互斥问题
大纲: 零。关于同步与互斥的多线程编程(一般思路)         1. 申请“信号量”句柄,初始化信号量。 (HANDLE ...)         2. 创建使用上线程的函数(函数中需要用到信号量)。(CreateSemaphore(...))         3. 创建线程(创建线程时用上第二步的函数)。(CreateThread(...))         4. 等待结束线程。(
【BCB】CB调用VC的dll,lib生成方法--VC dll转CB lib
CB所用lib生成方法 【运行】->输入【CMD】->输入【implib  c:\***.lib  c:\***.dll】
VC与BCB库文件之间的转换问题
经常碰到类似BCB contains invalid OMF record,type 0x21(possibly COFF)错误,该错误是由于BCB使用VC的lib兼容不足导致。 解决方法(1):从vc生成的动态库导出c++builder可用的导入库(注意:不是静态库),在Borland目录下找到Borland\CBuilder6\Bin里面有一个implib.exe,它可以将VC的DLL转译为
VC++和C++builder互相调用动态链接库DLL(VC++编的)笔记
关于动态链接库的具体介绍参考本人转载博客:进程间通信详解 - 动态链接库实现 下文说说自己编写的动态链接库,主要作用是实现用VC++编写的A程序和用C++builder编写的B程序之间的通信,其中涉及结构体,所以需要注意一下, 1>动态链接库myDLL        新建一个dll工程(MFC AppWizard(dll)),并命名myDLL,这个工程中有三种形式:
WIN32多线程编程( CreateThread 版本)
win32多线程没有想象中的那么难,从线程创建到运行再到结束所涉及的接口只需三个,而且大部分参数都使用默认值。本文没有讨论多线程间的互斥与同步,以后有可能会补上。
在用C++写函数时,在函数定义中的WINAPI代表什么含义?
在用C++写函数时,在函数定义中的WINAPI代表什么含义?例如:BOOL WINAPI IsNumeric(char *chString)与BOOL IsNumeric(char *chString)有什么区别? WINAPI其实就是__stdcall。 而__stdcall是C/C++调用约定的一种,意思是函数的参数被从右到左推送到堆栈上,被调用函数在返回之前从堆栈中弹出这些参数。