【发布时间】:2016-12-07 04:57:27
【问题描述】:
如果我这样声明一个函数:
#ifdef TEST_EXPORTS
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
TESTAPI int __stdcall myadd(int a, int b);
DLL 中的符号是_myadd@8,这对我来说非常有意义(也就是说,在阅读了这里的其他问题几个小时之后)。
但是 windows 库似乎做了一些不同的事情。他们也使用__stdcall(伪装成WINAPI),但是DLL中的符号没有名字修饰。如果上面的方法在 windows 库中,符号将是myadd。
我的猜测是他们使用 def 文件来给符号起别名。但是,当我链接到这些 DLL 之一时,为什么我的链接器会知道这一点?
windows 头文件用WINAPI 声明这些函数,所以如果我调用它们,链接器应该查找修饰名称,因为它是一个__stdcall 函数。然而不知何故,链接器知道删除名称装饰。
我试图通过编写一个小 DLL 并使用 def 文件删除名称装饰来复制这一点。正如预期的那样,我得到链接器错误,因为链接器仍在寻找修饰名称。我已经在纯 C 中完成了此操作,以确保 c++ 名称修改不会影响它。
编辑:澄清一下,MSVC 14.0 / VS2015,32 位
【问题讨论】:
-
请注意,x64 不使用名称修饰。
-
@JonathanPotter: “请注意,x64 不使用名称修饰。” - 仅适用于
extern "C"。 C++ 符号必须具有修饰的导出名称以进行重载解析。