我正在尝试使用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" . 我能清楚地知道lib / dll导出应该有"_C"而不是"_D",因为API_RETURN_TYPE是"signed __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链接器错误 .
1 回答
至少从Visual Studio 2003(!),"The __int8 data type is synonymous with type char"开始 .
显然,编译器不能使用不同的名称修改两种方式来命名相同的类型 .
同样富有洞察力的是this page,表明
__int8
是(已签名)char
但__int64
不是long long
;后者仅仅是等同的 .