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

Inl*_*ine 5 c++ linux gcc c++11

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

\n\n

我的朋友告诉我,如果加载 2 个使用不同编译器编译的库,或者当我从服务器调用函数时(这是在旧的 libstdc\xe2\x80\x8b++ 内部实现的),libstdc++ 静态链接可能会产生问题。

\n\n

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

\n

Max*_*kin 7

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

如果std::API 中公开了类型或者引发了 C++ 异常,则意味着共享库必须使用相同的标准库标头和定义的宏进行编译。在这种情况下,您可以动态链接到libstdc++主机应用程序附带的内容。

如果 API 中没有std::公开任何类型,并且共享库没有抛出异常,则可以静态链接到libstdc++. 但是,所有外部符号仍将从共享库中公开,因此当通过调用dlopenwithout RTLD_DEEPBINDflag 加载它时,它将使用主机应用程序中的同名符号(如果可用),而不是使用主机应用程序中的同名符号。您希望静态链接,这可能会导致您的朋友可能提到的未定义行为。为了避免这种情况,需要一个链接器版本脚本来将共享库中的所有符号设置为本地符号,并且仅将 API 符号公开为全局符号。就像是:

MYHALFLIFEPLUGIN_0.0 {
  global: half_life_foo,half_life_bar; # Explicitly list symbols to be exported.
  local: *; # Hide everything else.
};
Run Code Online (Sandbox Code Playgroud)

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

另外,请通读

更多细节。