首页 文章

为不正确生成的函数装饰名称

提问于
浏览
1

我正在尝试使用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 回答

  • 0

    至少从Visual Studio 2003(!),"The __int8 data type is synonymous with type char"开始 .

    显然,编译器不能使用不同的名称修改两种方式来命名相同的类型 .

    同样富有洞察力的是this page,表明 __int8 是(已签名) char__int64 不是 long long ;后者仅仅是等同的 .

相关问题