c++ - 库中所有符号的显式名称修改(也称为名称修饰)

标签 c++ c linux shared-libraries static-libraries

有什么方法可以在用 c(或 cpp)编写的库中显式地进行名称修改(也称为名称修饰)。我希望共享库中的所有符号的名称都经过修改。

考虑这个问题: Two library of different versions in an application 在这方面,如果我可以明确地让他们所有的名字都被破坏,我想我可以解决这个问题。可能 gcc 编译器本身有一些选项可以做到这一点。

最佳答案

您的问题是:

Is there any way to explicitly do name mangling (also called name decoration) in a library written in c(or cpp).I want all the symbols of my shared library to have their names mangled.

但是,我怀疑您不恰本地使用了术语name mangling。名称修改与库发布版本无关。如果您打算对库中导出的每个对象进行版本控制,那么有很多问题可以回答。就我个人而言,我会使用版本化的 namespace ——但这只是因为我(还)没有被它咬过。这是一个简单的例子:

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 时。如果您使用 class foo 的一个定义发布库的第 1 版,但随后第 2 版有一个不同的定义,那么这两个库不会兼容!不过,这才是重点。

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

阅读是相关但不是因果关系。相关问题正在反向回答您的问题。

许多操作系统都是用 C 语言编写的,这就是为什么在包含系统 header 时您会看到 extern "C" 的典型原因。这也是为什么当您尝试使用 header 中声明的内容时,您有时会看到链接器提示缺少函数,而该 header 的库是用 C 而不是 C++ 编译的。

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

使用 extern "C++" 本身 不会成为您的魔术。有一些 GCC 选项可以控制一些关于名称修饰的更具体的功能。因此,其次,看看那些。 GCC 手册页的(外部链接)位于:https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html

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

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

关于c++ - 库中所有符号的显式名称修改(也称为名称修饰),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57059186/

相关文章:

c++ - 如何让 Visual Assist 解析 Pro*C (*.pc) 文件?

c++ - Tensorflow C++ r1.13 构建错误 : 'TopK' is not a member of 'tensorflow::ops'

C++如何获取文件最近更改的时间戳?

linux - Linux 上的 Azure Web App - 服务器修补

c++ - 为什么默认构造函数在某些情况下默认不可用

java - 在大学完成计算机科学专业的第一年…夏天该做什么?

c - 检测到 glibc,realloc() : invalid pointer

python - 如何读取从通信端口写入的数据?

linux - Red Hat Enterprise 5.9 上的 PostgreSQL 从 9.1 升级到 9.3

json - 转换 json 文件