有什么方法可以在用 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++ 名称重整(这很奇怪,因为它应该默认完成),那么答案是双重的。首先,看一些相关的问题:
- Why would you use 'extern "C++"'?
- "Undefined reference to" error while linking object files
- "Undefined reference to" error when linking static C library with C++ code
阅读是相关但不是因果关系。相关问题正在反向回答您的问题。
许多操作系统都是用 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/