[英]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个解决方案:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.