共享对象中的符号名称与文件中.cpp函数不同
symbol name in shared object differs from function in .cpp file
在项目环境中,我想将共享对象的源文件从 c 更改为 cpp。我也确保更改其在CMakeLists.txt中的条目:
add_library(*name* SHARED *mysource*.cpp)
target_link_libraries(*name as target* *item*)
生成过程运行良好。不幸的是,当我尝试使用它时,出现一个错误,即找不到 .so 中的函数。
在使用 objdump -T 检查共享对象内的动态符号表后,我发现符号的名称与源文件中的名称不同。 例如
int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx);
成为
_Z17sr_plugin_init_cbP16sr_session_ctx_sPPv
在我的 Visual Studio 代码中,它说它可以正确构建对象并链接共享库,并且它还在输出中从 C 更改为 CXX,即使某些代码仅是 c++,也没有给我任何错误。
为什么符号名称会更改?
为什么符号名称会更改?
C++具有称为函数重载的功能。基本上发生的情况是,您声明了两个名称相同但略有不同的函数:
int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx);
int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx, int some_arg);
或者更糟糕的情况:
struct A {
# each of these functions can be different depending on the object
void func();
void func() const;
void func() volatile;
void func() volatile const;
};
函数的名称相同。Linker 看不到C++源,但它仍然必须区分这两个函数才能与它们链接。因此C++编译器会"破坏"函数名称,以便链接器可以区分它们。为了简单起见,它可能看起来像:
sr_plugin_init_cb_that_doesnt_take_int_arg
sr_plugin_init_cb_that_takes_int_arg
A_func
A_func_but_object_is_const
A_func_but_object_is_volatile
A_func_but_object_is_volatile_and_const
名称重整的规则很复杂,以使名称尽可能短。它们必须考虑任意数量的模板、参数、对象、名称、准数、lambda、重载、运算符等,并生成唯一的名称,并且它们必须仅使用与特定体系结构上的链接器兼容的字符。例如,这里是 gnu g++ 编译器使用的名称重整的参考。
符号名称_Z17sr_plugin_init_cbP16sr_session_ctx_sPPv
是由函数的编译器名称所破坏的。
非常感谢您的详细回答。我现在明白这个问题了。 经过快速搜索,我找到了解决问题的方法。像这样封装函数原型可以避免名称重整。
extern "C" {
// Function prototypes
};
相关文章:
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 命名空间中具有.h和.cpp文件的类
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- 有充分的理由在h文件中使用include保护而不是cpp文件吗
- 如何在cpp文件之间切换窗口?在Qt中
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 我有两个类需要在同一 cpp 文件中相互引用,但第一个类无法识别第二个类类型的对象
- .h 和.cpp文件分离时出错,但仅使用 .h 文件时没有错误.我做错了什么?
- 库标题在标题中不可见,但在 cmake build 下.cpp文件中完全可见.为什么?
- C++ 链接到单独的.cpp文件说"multiple definitions"
- 在 cpp 文件中隐藏采用模板参数引用的方法
- 如何使用 samtools C API 构建一个简单的主.cpp文件
- 包含在.cpp文件中包含在 .h 文件时包含
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 如何使用线程类编译 cpp 文件?
- 使用 Powershell 命令将 cpp 文件的文件夹编译为 GNU 的 g++
- 我应该将外部标头放在 .h 文件还是.cpp文件中?
- 从另一个 cpp 文件更改结构内、映射键内的变量