【问题标题】:64bit name mangling for c++c++ 的 64 位名称修改
【发布时间】:2012-11-03 08:51:16
【问题描述】:

我有一段代码,其中包含以下行

  #pragma comment(linker, "/include:_test@12") 

当我使用配置类型为 32 位的 C++ Visual Studio 2010 编译代码时,使用此代码的项目工作正常(我也在 32 位 Windows 机器上)。

当我将机器更改为 64 位并使用使用 C++ Visual Studio 2010 编译的 x64 配置时出现链接错误。

32 位和 64 位的 C++ 名称修改是否不同?如果是这样,我在哪里可以找到 64 位 C++ 名称修改约定?

【问题讨论】:

    标签: c++ visual-studio-2010 64-bit name-mangling


    【解决方案1】:

    是的,名称修饰在 32 位和 64 位之间是不同的。一篇涵盖确切格式的合理文章可以是found here。但是,通过简单地编译到两个目标并检查生成的映射文件,您可以很快分辨出主要差异。根据我的经验,它们几乎完全相同(64 位添加了一个小数据,可能会改变其他数据)。

    简单示例:void foo();

    32bit: ?foo@A@@QAEXXZ
    64bit: ?foo@A@@QEAAXXZ
    

    对于未损坏的 std 调用,长度后缀可能有很大不同,具体取决于参数堆栈的使用情况。 VC++ 的默认 64 位设置不添加下划线,也不编码长度后缀。以下是使用纯开箱即用设置编译的 32/64 位配置:

    extern "C" int _stdcall func2(int, int, char*);
    
    32bit: _func2@12
    64bit: func2
    

    没什么意义,是吗。

    完成电路,unmangled _cdecl,它是这样做的:

    extern "C" int _cdecl func2(int, int, char*);
    
    32bit: _func2
    64bit: func2
    

    如果他们似乎特意让你知道你在拉入或输出什么,那么有证据表明你可能是正确的。

    【讨论】:

    • 实际上可能有很大不同...如果test接收到三个指针参数,那么它将从12变为24...啊,这也不是C++函数。这似乎是一个stdcall C 函数。
    • 我在哪里可以了解这一点。我对这些概念很陌生。我也认为我的是标准调用,你给出的例子是 cdecl。我还有其他几个电话,例如#pragma comment(linker, "/export:test@0=test") 我应该如何更改这些电话。澄清这些的参考资料会很棒。
    • 有很多关于 C++ 名称修改的文档(我给你链接了其中一个)。您似乎正在使用 extern "C" _stdcall 进行导出,如上所示,在 32.vs.64 位中是不同的。从字面上看,MS 和 Wiki 上都有文章。虽然与 VB 相关,但我喜欢 this post,因为它在谈论它方面做得不错。不过,无论如何,恐怕您必须将#pragmas 清理为#ifdef WIN64 并导入或导出适当的名称。
    • 据我所知,唯一可用于 64 位系统的调用约定是 vectorcall 和默认的 x64 调用约定(这似乎是 fastcall 的一个版本,据我所知网上找)。因此,__cdecl__stdcall__fastcall__thiscall 在编译为 64 位时都会被忽略。
    • 维基百科页面已迁移至:en.wikiversity.org/wiki/Visual_C%2B%2B_name_mangling
    猜你喜欢
    • 2011-06-07
    • 1970-01-01
    • 2017-05-22
    • 2017-11-28
    • 2020-04-28
    • 2011-11-19
    相关资源
    最近更新 更多