我正在尝试使用 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”。
我摆弄了一堆编译器设置,但没有运气。正如这里所建议的(在 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 链接器错误。