我有一个程序,通过dynamic加载一个plugin_name.so函数来实现一个插件系统(像往常一样)。
但反过来,我有一个静态的“帮手”库(让我们称之为helper.a),其function是从主程序和插件的主要function。 它们不必以任何方式进行互操作,它们只是用于文本操作等的辅助function。
这个程序一旦启动,就无法重新加载或重新启动,这就是为什么我期望从插件中获得新的“帮助”function,而不是从主程序。
所以我questin是..是否有可能迫使这个“插件function代码”在。SO使用(静态链接?)一个不同的(也许更新的)版本的“帮手”比主程序?
这怎么可能呢? 也许通过静态链接或以其他方式将helper.a添加到plugin_name.so?
Nick Meyer的答案在Windows和AIX上是正确的,但在默认情况下在其他任何UNIX平台上不太可能正确。
在大多数UNIX平台上,运行时加载程序为所有符号维护一个名称空间,所以如果您在a.out
定义foo_helper
,并在plugin.so
定义plugin.so
,然后从其中调用foo_helper
,则运行时加载程序可见的第一个定义通常来自a.out
)是默认情况下用于这两个调用。
另外,由于foo_helper
不能从a.out
导出(因此对运行时加载器来说可能是不可见的),除非使用-rdynamic
标志或其他一些共享库引用它,否则图片会变得复杂。 换句话说,当Nick描述它们时,事情可能会起作用,然后你将共享库添加到a.out
链接行,而且它们不再以这种方式工作。
在ELF平台(如Linux)上,您可以很好地控制符号可见性和绑定。 请参阅GCC
手册页中的-fvisibility=hidden
和-Bsymbolic
描述,以及链接器手册页中的-Bsymbolic
。
大多数其他UNIX平台也有一些控制符号绑定的方法,但是这必须是特定于平台的。
如果你的主程序和动态库都静态链接到helper.a,那么你不需要担心混合版本的helper.a(只要你不需要像helper.a .exe和.so界限)。
当你链接到它的时候,helper.a所需的代码被插入到实际的二进制文件中。 所以当你从.exe调用helper.a的时候,你将会从你的可执行映像的代码段执行代码,当你从.so调用helper.a时,你将会执行代码地址空间.so被加载。 即使你在helper.a中调用了相同的函数,你也可以调用该函数的两个不同的“实例”,具体取决于调用是从.exe还是.so调用的。
我想这个问题和你的一样。 如何强制从一个静态库中的符号被包含在共享库的构建?
–whole-archive连接器选项应该这样做。 你会用它作为例如
gcc -o libmyshared.so foo.o -lanothersharedlib -Wl, – whole-archive -lmystaticlib
它对我有用。