Gcc Unix程序使用共享库中的错误函数

Gcc Unix程序使用共享库中的错误函数,gcc,shared-libraries,unix,Gcc,Shared Libraries,Unix,我正在重构一套旧的实用程序,并创建一个新的服务器,它将使用所有这些工具的通用代码来统一它们的功能,并允许远程客户端进行外部访问。对于每个实用程序,我将获取服务器所需的代码,并将其重构到共享库中,以便实用程序和服务器现在都将链接到共享库。由于这些实用程序的前实现者的工作方式,他们几乎只是在需要创建新实用程序时复制和粘贴所有内容,因此有大量函数具有相同的签名(即XML解析器的回调),但在内部执行不同的操作 当我运行独立的实用程序时,它们经过重构以链接共享代码,它们工作得非常好。当我尝试使用与给定实用

我正在重构一套旧的实用程序,并创建一个新的服务器,它将使用所有这些工具的通用代码来统一它们的功能,并允许远程客户端进行外部访问。对于每个实用程序,我将获取服务器所需的代码,并将其重构到共享库中,以便实用程序和服务器现在都将链接到共享库。由于这些实用程序的前实现者的工作方式,他们几乎只是在需要创建新实用程序时复制和粘贴所有内容,因此有大量函数具有相同的签名(即XML解析器的回调),但在内部执行不同的操作

当我运行独立的实用程序时,它们经过重构以链接共享代码,它们工作得非常好。当我尝试使用与给定实用程序具有相同功能的服务器时,服务器使用的代码来自链接到的第一个库,而不是它应该从中获取功能的库

例如,我有一个通用xml库解析的设备A、B、C的xml,但每个设备都有自己的共享库libA、libB、libC,供服务器使用。当我调用服务器为设备C发送xml时,它使用的是libA中的函数“handleStarteElement”,而不是libC中具有相同名称和签名的函数,即使共享库只在内部声明这些函数,而不共享任何提到这些内部回调以解析xml的头

有人能给我解释一下为什么它没有读取正确的函数,以及将来如何避免这种情况

服务器的My makefile具有以下用于编译主程序的标志:

-I../include -L../lib -lA -lB -lC

每个共享库都几乎不使用共享库的标志,并且没有使用-fPIC。

当与
-l
标志一起使用时,共享库应该与非共享库一样工作,特别是不支持存在具有相同名称的多个函数。您已经有点幸运了,因为服务器可以运行

如果我正确地理解了您的问题,那么具有相同名称的函数将不会在共享库之外被“看到”。共享库有一个“动态符号表”,其中列出了共享库导出和导入的符号。使用GNU工具,您可以使用
nm-dlibfoo.so
查看其内容。传统的Unix链接器通过使用对象文件中的所有公共实体(即非静态函数和全局变量)来填充该符号表。这里需要的是符号表的更可控的构造。如果您的代码使用GNU工具(例如,您正在Linux上运行),那么您需要阅读,特别是第2.2节。短篇故事:ELF格式支持您所追求的,有几种工具/方法可以实现它

然而,在您的位置上,我会使用一些基于
sed
的脚本来用唯一的名称重命名有问题的函数。对原版过度复制的贴纸采取一些报复行动也可能是适当的


您应该使用
-fPIC
。在某些体系结构上不使用
-fPIC
作为共享库是一个致命的错误。因为您的代码不会崩溃,所以我认为您在x86硬件上运行。

您确实正确地理解了这个问题,并且我确实希望符号表的构造更加可控。我实际上是从一台运行Gentoo的x86机器(内核为2.6)交叉编译到一台运行2.4内核的PPC405嵌入式机器。我会读一读这篇文章,看看我是否可以操纵符号表的构造,否则我只能重命名一堆废话。非常感谢你,我看完了这篇文章。仅仅将我的内部模块函数重新定义为静态函数(我应该首先知道这样做)就足以防止它们在符号表中被公开访问。再次感谢你。