动态库中的libstdc ++静态链接 [英] libstdc++ static linking in dynamic library

查看:438
本文介绍了动态库中的libstdc ++静态链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

To understand question I should tell you more about program that loads dynamic library. It's Half-Life Dedicated server. It uses old libstdc++ which is located next to executable. To avoid issues, when using features from new standard library I usually link my project staticaly to libstdc++.

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

My friend told me that libstdc++ static linking can create problems, if 2 compiled with different compilers libraries are loaded or when I call function from server (which is internally implemented in terms of old libstdc​++).

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

Is it true? How can I resolve this issue?

推荐答案

您的共享库公开的API必须使用主机应用程序期望的相同ABI,即

The API your shared library exposes must use the same ABI that the host application expects, i.e. the types involved must be of the same layout, size and alignment.

如果公开了 std :: 类型,则这些类型必须具有相同的布局,大小和对齐方式。否则会抛出C ++异常,这意味着共享库必须使用定义的相同标准库头和宏进行编译。在这种情况下,您可以动态链接到主机应用程序随附的 libstdc ++

If there are std:: types exposed in the API or it throws C++ exceptions, then that means the shared library must be compiled using the same standard library headers and macros defined. In this case you can link dynamically to that libstdc++ that comes with the host application.

如果没有< API中公开的code> std :: 类型,并且共享库没有引发任何异常,您可以静态链接到 libstdc ++ 。但是,所有外部符号仍将从共享库中公开,因此在加载时调用 dlopen 而没有 RTLD_DEEPBIND 标志,它将使用主机应用程序中具有相同名称的符号(如果可用),而不是您希望静态链接的符号,这可能会导致您的朋友可能引用的未定义行为。为避免这种情况,需要使用链接程序版本脚本,以使共享库中的所有符号都位于本地,并且仅将API符号公开为全局符号。

If there are no std:: types exposed in the API and no exceptions are thrown from the shared library, you can link statically to libstdc++. However, all external symbols are still going to be exposed from the shared library, so that when it is loaded with a call to dlopen without RTLD_DEEPBIND flag, it will use the symbols with the same name from the host application if they are available instead of the ones you hoped to link in statically, which may cause that undefined behavior your friend probably refers to. To avoid this, a linker version script is required to make all symbols in your shared library local and only expose the API symbols as global. Something like:

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

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

And direct the linker to use this script with -Wl,--version-script=<filename> compiler linker option (LDFLAGS). In addition to -static-libstdc++ option, you will need -static-libgcc linker option.

另外,请通读

  • https://gcc.gnu.org/wiki/Cxx11AbiCompatibility
  • ABI Policy and Guidelines

了解更多信息。

这篇关于动态库中的libstdc ++静态链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆