在标准库中静态链接时如何支持动态插件?

How to support dynamic plugins when statically linking in standard libraries?

假设一个应用程序 myapp.exe 是使用 g++ 构建的,它使用标志 -static-libstdc++ 以便它可以安装在没有 libstdc++.so 的环境中。 myapp.exe 还添加了对某些函数 plugf 的插件支持,这些函数可以通过 dlopen 从分片库中动态加载。

如果 libplug.so 是这样一个也链接到 libstdc++ 的插件库,它如何以能够与 myapp.exe 一起工作的方式做到这一点?

如果 libstdc++ 是动态链接的,这很简单,因为 myapp.exelibplug.so 都可以使用相同的动态加载标准库,但我不清楚如何做最好这与静态链接的标准库。

我正在考虑的一种方法是让 libplug.so 也使用标志 -static-libstdc++,然后使用 version script

{
  global: plugf;
  local: *;
};

以确保使用其标准库版本,但这意味着将有两个 libstdc++ 副本加载到内存中。我知道这种方法不会受到 C++ 标准的支持,因为它会违反 ORD,但 libstdc++ 是否以任何方式支持它? manual 部分的 Multiple ABI testing 部分确实引用了一个听起来相似的场景。

是的,这个解决方案可行,但是

  • 由于代码重复引入了一定的开销
  • 如果您尝试在 plugin/app 之间传递 STL 对象,由于 ABI changes in recent libstdc++
  • ,它可能会中断

删除由 std::allocator 在不同 C++ 运行时分配的对象应该在 Linux 上工作,尽管我在 libstdc++ 文档中找不到关于此的明确声明。正如 Mikhail 在评论中指出的那样,它确实在 Windows 上失败了。