DLL导出符号注意事项
2024-03-17 17:33:41
导出DLL函数有两种方法:
- 使用 __declspec(dllexport) 语法。
- 使用 .def 文件。
但两者是有区别的,比如有这样一个函数签名int __stdcall Foo(int);
方法 | lib符号名称 | dll导出名称 |
---|---|---|
__declspec(dllexport) | ?Foo@@YGHH@Z | ?Foo@@YGHH@Z |
.def file | ?Foo@@YGHH@Z | Foo |
用.def
文件导出的函数名称是干净的,也方便其他程序调用。
而 __declspec(dllexport)
导出的名称被修饰了,只适合C++程序使用。
extern “C”
extern "C"
的主要目的就是抑制C++编译器修饰符号名称,比如将 Foo 函数签名修改如下extern "C" __declspec(dllexport) int __stdcall Foo(int);
导出符号变为:
方法 | lib符号名称 | dll导出名称 |
---|---|---|
__declspec(dllexport) | _Foo@4 | _Foo@4 |
.def file | _Foo@4 | Foo |
总结
- 对于 lib 静态库,用 __declspec(dllexport) 导出,用 __declspec(dllimport) 导入。不需要
extern "C"
。 - 对于 dll 动态库,如果需要供非C++程序使用,用
.def
文件声明导出函数,而不是__declspec(dllexport)
。 - 在导出 dll 函数时,
EXTERN_C
虽然不是必须的,但是建议加上,可供C语言调用。
相关阅读
how does extern “C” allow C++ code in a C file?
Importing and Exporting
Viewing Decorated Names
GCC and MSVC C++ Demangler