【发布时间】:2017-05-12 17:17:10
【问题描述】:
我正在尝试使用 Visual Studio 2017(从 Visual Studio 6.0 升级)将一些第三方 C++ 代码编译到我的 32 位 C++ 应用程序中。我有来自第三方的 .h 文件和 .lib 文件。链接器正在查找库,但没有找到其中包含的修饰名称。这似乎是因为编译器正在用“char”替换“__int8”。
链接器错误是:
LNK2019 unresolved external symbol "signed char __cdecl Check_The_Thing(void)" (?Check_The_Thing@@YACXZ) referenced in function (redacted)
函数在.h中定义:
_declspec(dllexport) API_RETURN_TYPE Check_The_Thing ( void );
API_RETURN_TYPE 定义在 .h:
_declspec(dllimport) typedef signed __int8 int_8;
_declspec(dllimport) typedef int_8 API_RETURN_TYPE;
使用 dumpbin /exports,我可以看到我的 lib 和关联的 dll 导出 Check_The_Thing:
?Check_The_Thing@@YA_DXZ (__int8 __cdecl Check_The_Thing(void))
使用 undname,我可以看到 lib 中的修饰名称正确评估:
Undecoration of :- "?Check_The_Thing@@YA_DXZ"
is :- "__int8 __cdecl Check_The_Thing(void)"
但是编译器生成的修饰名称没有正确评估(基于代码):
Undecoration of :- "?Check_The_Thing@@YACXZ"
is :- "signed char __cdecl Check_The_Thing(void)"
根据https://en.wikiversity.org/wiki/Visual_C%2B%2B_name_mangling,YACXZ 中的“C”计算为“signed char”,“_D”计算为“__int8”。我无法弄清楚为什么编译器将 API_RETURN_TYPE 解释为“char”而不是“__int8”。很明显,lib/dll 导出应该具有“_C”而不是“_D”,因为 API_RETURN_TYPE 是“签名的 __int8”,而不仅仅是“__int8”。
我已经摆弄了一堆编译器设置,但没有运气。正如这里 (Cannot find decorated function name in dll) 所建议的那样,我确定我使用的是 MBCS 而不是 Unicode(之前未设置),但这也没有任何区别。
将 API_RETURN_TYPE 专门定义为 __int8 没有区别,只是将“C”更改为“D”(进度!),同样 undname 将返回类型显示为“char”而不是“signed char”。将函数定义的返回类型更改为 __int8 与更改 API_RETURN_TYPE 的效果相同。
所以,我的问题是:如何强制编译器使用“__int8”(或“_D”)而不是 char(“D”)正确定义我的导出?
旁注:链接器错误在使用 __int16、__int32 和 __int64 的情况下是相同的。
编辑:实际上,该库定义了 __int64 类型,但我没有使用任何类型。没有任何 __int64 链接器错误。
【问题讨论】:
标签: c++ visual-studio visual-studio-2017 name-decoration