C++名称修饰是否具有确定性?

6

我希望在托管代码中加载非托管C++ DLL,并调用已经被编译的外部函数的 GetProcAddress。我的问题是:C++ 编译器生成的名称是否是确定性的?也就是说,如果原始签名没有更改,那么名称是否总是转换为相同的名称?请注意保留 HTML 标记。


可能是什么是名称修饰,它是如何工作的?的重复问题。 - Kirill V. Lyadvinsky
1
当编译器升级版本时,它可能会改变名称混淆的方式。只要您坚持使用特定编译器和特定版本,就应该没问题。请注意,一些编译器在运行时提供了一个 API,允许您将混淆的名称进行转换。您可以查看 c++filt 的工作原理,了解有关 gcc 混淆库的内容。 - Martin York
@Martin。这是很棒的信息。我只能使用Windows平台。这告诉我需要为可能出现的破坏性变更做好准备或者寻找其他方法。 - Blanthor
如果您动态加载DLL并需要手动解析符号,则通常最好提供C接口(因为没有名称修饰并且ABI是定义的(基于每个平台))。然后,C函数可以返回指向工厂对象的指针,该对象允许您在DLL中创建所有C ++对象。 - Martin York
3个回答

6

这并没有在标准中具体规定,在我个人的经验中,它在同一编译器的不同版本之间肯定会有所改变,尽管它必须在一些固定的情况下是确定性的,因为否则就无法链接两个单独编译的模块。

如果您正在使用 GetProcAddress,那么将函数导出为 extern "C" 会更加清晰,这样它们的名称就不会被混淆。


4
一种编译器的特定版本会始终以相同的方式混淆名称,否则它将无法与自己生成的内容链接。除此之外,一切皆不确定。 - Eltariel

2

0

名称修饰在每个编译器中处理方式不同(可能有,也可能没有标准)。如果您在C++代码中使用纯C函数,可以使用extern "C"来抑制C函数的名称修饰,以便编译器能够找到它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接