库中所有符号的显式名称重整(也称为名称修饰)

Explicit name mangling (also called name decoration) for all symbols in a library

本文关键字:符号      更新时间:2023-10-16

有没有办法在用c(或cpp)编写的库中显式地进行名称重整(也称为名称修饰)。我希望我的共享库的所有符号的名称都被破坏。

考虑这个问题: 应用程序中两个不同版本的库 在这种情况下,如果我能明确地把他们所有的名字都弄乱,我想我可以解决这个问题。gcc编译器本身可能有一些选项可以做到这一点。

你的问题是:

有没有办法在用c(或cpp)编写的库中显式地进行名称重整(也称为名称修饰)。我希望我的共享库的所有符号的名称都被破坏。

但是,我怀疑您不恰当地使用了术语名称。名称重整与库发布版本无关。如果您打算对库中导出的每个对象进行版本控制,那么有很多问题需要回答。就个人而言,我会使用版本化的命名空间——但只是因为我(还没有)被它咬过。下面是一个快速示例:

namespace mylibrary {
namespace v1 {
class foo {};
}
using foo = v1::foo;
}
mylibrary::foo f; // mylibrary::v1::foo

。然后在以后的版本中...

namespace mylibrary {
namespace v1 {
class foo {};
}
namespace v2 {
class foo;
}
using foo = v2::foo;
}
mylibrary::foo newer_f; // mylibrary::v2::foo
mylibrary::v1::foo older_f;

当然,您可以拥有许多排列。并且有很多警告,特别是如果您有模板化代码或使用 ADL。如果您发布的库版本 1 具有一个class foo定义,但版本 2 具有不同的定义,则这两个库将不兼容!不过,这就是重点。

但是,如果我不正确,并且您确实想在您的C++库中强制执行C++名称重整(这很奇怪,因为它应该默认完成),那么答案是双重的。首先,看一些相关问题:

  • 为什么要使用"外部"C++"?
  • 链接对象文件时出现"未定义引用"错误
  • 将静态 C 库与C++代码链接时出现"未定义的引用"错误

读数是相关的,但不是因果关系。相关问题反过来回答了您的问题

许多操作系统都是用 C 编写的,这通常是您在包含系统标头时会看到extern "C"的原因。这也是为什么当你尝试使用库是用 C 而不是 C++ 编译的标头中声明的内容时,有时会看到链接器抱怨缺少函数。

因此,要朝另一个方向(在您的方向上):在您的头文件中,您可以将导出声明为extern "C++".这告诉编译器在导入或导出对象时专门使用损坏的名称。

使用extern "C++"本身不会成为你的魔术。有一些 GCC 选项可以控制有关名称重整的一些更具体的功能。所以,其次,看看这些。GCC手册页面的(外部链接)在这里:https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html

任何提及 ABI 的选项(例如-fabi)都可能会影响您。"-fabi" 标志与"应用程序二进制接口"相关。您可能还想了解有关这些术语的更多信息。什么是应用程序二进制接口有一些很好的答案,描述了什么是 ABI 以及如何开始推理它们。"-Wabi"将告诉GCC在检测到潜在的ABI冲突时发出警告。但是,就像C++的所有事情一样,它并非万无一失。如果存在可能无法检测到的名称重整问题,我不会感到惊讶。如果您混合使用异构编译器供应商或版本,则尤其如此。

重要的是:混合ABI可能会是一个令人头疼的问题。我会非常担心 ABI 不兼容性被强制在一起并导致非常难以调试的未定义行为!