GCC / Linux:添加静态库到.so?

我有一个程序,通过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

它对我有用。