c++ - 动态库中的 libstdc++ 静态链接

标签 c++ linux c++11 gcc

为了理解问题,我应该告诉你更多关于加载动态库的程序。这是半条命专用服务器。它使用位于可执行文件旁边的旧 libstdc++。 为避免出现问题,在使用新标准库中的功能时,我通常将我的项目静态链接到 libstdc++。

我的 friend 告诉我 libstdc++ 静态链接会产生问题,如果加载了 2 个使用不同编译器库编译的库,或者当我从服务器调用函数时(这是根据旧 libstdc++++ 内部实现的)。

这是真的吗?我该如何解决这个问题?

最佳答案

您的共享库公开的 API 必须使用与主机应用程序期望的相同的 ABI,即涉及的类型必须具有相同的布局、大小和对齐方式。

如果有std:: API 中公开的类型或抛出 C++ 异常,则这意味着必须使用相同的标准库头文件和定义的宏来编译共享库。在这种情况下,您可以动态链接到那个 libstdc++随主机应用程序一起提供。

如果没有std:: API 中公开的类型并且共享库中没有抛出异常,您可以静态链接到 libstdc++ .然而,所有外部符号仍然会从共享库中暴露出来,因此当调用 dlopen 加载它时。没有RTLD_DEEPBIND标志,它将使用主机应用程序中具有相同名称的符号(如果它们可用)而不是您希望静态链接的符号,这可能会导致您的 friend 可能提到的未定义行为。为避免这种情况,需要链接器版本脚本将共享库中的所有符号设为本地,并且仅将 API 符号公开为全局。像这样的东西:

MYHALFLIFEPLUGIN_0.0 {
  global: half_life_foo,half_life_bar; # Explicitly list symbols to be exported.
  local: *; # Hide everything else.
};

并指示链接器将此脚本与-Wl,--version-script=<filename> 一起使用编译器链接器选项 ( LDFLAGS )。除了-static-libstdc++选项,您将需要 -static-libgcc链接器选项。

另外,仔细阅读

了解更多详情。

关于c++ - 动态库中的 libstdc++ 静态链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44783614/

相关文章:

c++ - 将动态结构数组复制到另一个 C++

c++ - 在 Windows 上等待进程随机失败

Linux 和虚拟机

c++ - 右值引用和左值引用有什么区别? (代码生成器)

c++ - Visual Studio C++ 项目中的奇怪内存泄漏

C++ "this"类属性

c++ - 堆二叉树打印方法

linux - 在 sed 中搜索和替换 html 标签(带斜杠)

linux - 为什么两个进程同时使用一个java命令

c++ - shared_ptr<T> 到 shared_ptr<T const> 和 vector<T> 到 vector<T const>