Visual Studio无需DEF文件导出无修饰__stdcall DLL函数及调用约定识别问题
DLL开发相关问题解答
问题1:如何查看已有DLL文件中函数的调用约定是__stdcall还是__cdecl
- 你可以使用Visual Studio自带的
dumpbin工具查看导出函数的名称修饰,以此判断调用约定:- 打开Visual Studio的开发者命令提示符
- 执行命令:
dumpbin /exports <你的DLL文件路径> - 根据输出的函数名判断:
- 若函数名格式为
_函数名@参数总字节数(比如示例中的_TestFunktion@0),则为__stdcall调用约定 - 若函数名格式为
_函数名,没有@加数字的后缀,则为__cdecl调用约定
- 若函数名格式为
- 注意:64位Windows环境下微软统一了调用约定,
__stdcall和__cdecl没有差异,导出的函数不会有上述名称修饰,无法通过该方法区分。
问题2:无需DEF文件导出无修饰名的__stdcall函数的实现方法
可以通过给链接器传递/EXPORT参数实现需求,不需要修改现有函数代码,也不需要引入DEF文件,有两种操作方式:
方式1:代码中添加编译指令
在你的函数声明/实现所在的代码文件中加入以下预处理指令即可:
// 等号左侧为你要导出的无修饰函数名,右侧为编译器生成的修饰名,参数总字节数按实际情况计算 #pragma comment(linker, "/EXPORT:TestFunktion=_TestFunktion@0") __declspec(dllexport) int __stdcall TestFunktion(void) { return 0; }
注:修饰名后缀的数字为函数所有参数的总字节数,比如函数有2个int类型参数,总字节数为8,修饰名就是
_TestFunktion@8。
方式2:在项目配置中添加链接器参数
打开Visual Studio项目属性,依次进入「配置属性 -> 链接器 -> 命令行」,在「附加选项」输入框中添加以下内容,保存后重新编译即可:
/EXPORT:TestFunktion=_TestFunktion@0
注意事项
- 上述操作仅针对32位DLL有效,64位DLL默认导出的
__stdcall函数就没有名称修饰,不需要额外配置。 - 如果需要同时兼容32位和64位编译,可以使用条件编译区分:
#ifdef _WIN32 #ifndef _WIN64 // 仅32位配置下添加该导出指令 #pragma comment(linker, "/EXPORT:TestFunktion=_TestFunktion@0") #endif #endif
内容的提问来源于stack exchange,提问作者Aleksej
相关产品推荐
相关产品推荐

