2016-11-18 40 views
1

有一组插件的一个应用程序,所有链接到一个共同的基础库。基础库定义了一个单例,它维护着每个插件中所有对象构造函数的列表。我如何创建共享库的具体实例单

在windows上,我可以创建这个基本库作为一个静态库,因此单例的副本放置在每个插件中。 但是在Linux上我有一点相反的问题as this fellow.

我已经试过到目前为止以下内容:

  • 建基地作为共享库(按照原作者)
  • 建基地作为静态与-fPIC
  • 建基地与-fPIC为静态,明确的CMake删除-rdynamic

我真的想保持程序结构与现在一样,通过让singleton定义驻留在基本库内部,让每个插件拥有自己的实例。我已经尝试将定义移到每个插件中,但我真的很想避免这种情况。 本质上我想重现他认为的一个错误。但是他完全定义在一个头文件,它是有道理的,我认为每个插件会再有它自己的类的实例化他的单,我就另一方面也要编入基础库单身的定义。

回答

1

最好的解决方案是在Windows上做同样的事情:将基础库编译为归档(静态)库并将其链接到每个插件中。 (这需要使用-fPIC编译基本库。)

原因不起作用:您没有控制从插件导出的函数。

在Windows上,除非您明确指出插件的功能DLLEXPORT,否则它仍然是内部的。在Linux中,默认是相反的,并且当两个共享库导出同一符号,第一个加载获胜。

所以,这里是你需要做什么:

  1. 编译基础库-fPIC -fvisibility=hidden
  2. 对于您想从插件出口,增加__attribute__((visibility("default")))的特定功能。

完成此操作后,运行nm -D new-plugin.so并与nm -D old-plugin.so进行比较。您应该看到,旧的插件出口的一切,以及新的插件出口功能标记要出口。

另一种替代方法是使用linker script控制符号可见。

+0

另一个机会是[使用可见性编译指示](https://gcc.gnu.org/onlinedocs/gcc/Visibility-Pragmas.html)。 – yugr

+0

谢谢你的回应,我会在接下来的几天里进行测试,并确认这是否适合我的工作。 –

+0

经过测试和验证,这适用于我想要做的事。非常感谢。 –