如何创建共享库特定的单例实例 [英] How to create shared library specific singleton instances

查看:116
本文介绍了如何创建共享库特定的单例实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为应用程序提供了一组插件,这些插件都链接到一个公共的基本库.基础库定义了一个单例,该单例维护每个插件中所有对象构造函数的列表.

I have a set of plugins for an application which all link to a common base library. The base library defines a singleton which maintains a list of all object constructors in each plugin.

在Windows上,我可以将此基础库创建为静态库,因此在每个插件中都放置了一个单例的副本. 但是在Linux上我有一些相反的问题

On windows, I can create this base library as a static library and thus a copy of the singleton is placed in each plugin. However on Linux I have a bit of the opposite problem as this fellow.

到目前为止,我已经尝试了以下方法:

I've tried the following so far:

  • 将基础构建为共享库(根据原始作者)
  • 使用-fPIC将基础构建为静态
  • 使用-fPIC将基础构建为静态,在CMake中显式删除-rdynamic

我真的很想通过使单例定义驻留在基础库中并使每个插件拥有自己的实例,来保持程序结构与现在相同.我已经尝试过将定义移动到每个插件中,但是我真的很想避免这种情况. 本质上,我想重现他认为的错误.但是,他完全在一个头文件中定义了他的单例,这对我来说很有意义,即每个插件都将具有自己的类实例化,而另一方面,我将单例的定义编译到了基础库中.

I would really like to keep the program structure the same as it is now by having the singleton definition reside inside of the base library for each plugin to have it's own instance. I have experimented with moving the definition into each plugin but I'd really like to avoid that. Essentially I want to reproduce what he considers a bug. However he defines his singleton completely in one header file which makes sense to me that each plugin would then have its own instantiation of the class, I on the other hand have the definition of the singleton compiled into the base library.

推荐答案

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

The best solution for you is to do the same thing you do on Windows: compile the base library as an archive (static) library and link it into each of the plugins. (This requires compiling the base library with -fPIC.)

此操作不起作用的原因:您无法控制要从插件导出的功能.

The reason this didn't work: you are not controlling the functions you are exporting from the plugins.

在Windows上,除非您显式地DLLEXPORT插件中的函数,否则该函数仍是内部的.在Linux上, default 是相反的,并且当两个共享库导出相同的符号时,第一个加载的符号将获胜.

On Windows, unless you explicitly DLLEXPORT a function from the plugin, it remains internal. On Linux, the default is the opposite, and when two shared libraries export the same symbol, the first one loaded wins.

所以,这是您需要做的:

So, here is what you need to do:

  1. 使用-fPIC -fvisibility=hidden
  2. 编译基础库
  3. 对于要从插件中导出的特定功能,请添加__attribute__((visibility("default"))).
  1. Compile base library with -fPIC -fvisibility=hidden
  2. For the specific functions that you do want to export from plugins, add __attribute__((visibility("default"))).

完成此操作后,运行nm -D new-plugin.so并与nm -D old-plugin.so进行比较.您应该看到,旧插件会导出所有内容,而新插件只会导出您标记为要导出的功能,仅 .

Once you've done this, run nm -D new-plugin.so and compare to nm -D old-plugin.so. You should see that the old plugin exports everything, and the new plugin exports only the functions you marked for export.

另一种替代方法是使用链接脚本来控制符号可见性.

Another alternative is to use linker script to control symbol visibility.

这篇关于如何创建共享库特定的单例实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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