繁体   English   中英

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

[英]libstdc++ static linking in dynamic library

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

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

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

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

如果在API中暴露了std:: types或者它抛出了C ++异常,那么这意味着必须使用定义的相同标准库头和宏来编译共享库。 在这种情况下,您可以动态链接到主机应用程序附带的libstdc++

如果API中没有公开std:: types,并且没有从共享库中抛出异常,则可以静态链接到libstdc++ 但是,所有外部符号仍然会从共享库中公开,因此当它在没有RTLD_DEEPBIND标志的情况下加载dlopen ,它将使用主机应用程序中具有相同名称的符号(如果它们可用)而不是您希望静态链接的那些,这可能会导致您的朋友可能引用的未定义行为。 为避免这种情况,需要使用链接器版本脚本来使共享库中的所有符号都是本地的,并且只将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链接器选项。

另外,请仔细阅读

更多细节。

是的,它是真的。 最简单的示例是,如果在库中创建一个带有new的对象,并在另一个不使用相同STL的库中将其delete

你有2个解决方案:

  • 使用STL的动态链接
  • 确保不兼容性不跨越二进制文件(库,exe)的边界。 这样做的难点是让你的库只公开一个C API(没有C ++)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM