如果库链接了两次,程序如何确定使用哪个版本?

时间:2013-01-09 08:07:43

标签: linker dependencies shared-libraries

在为服务器编写共享库时,我遇到了以下情况。

为了便于理解:

  1. 让我们调用服务器框架fwA
  2. 我写的名为libB的共享库
  3. 由fwA和libB链接的不同版本的库,名为libC1和libC2
  4. fwA通过dllopen加载libB

    以下是我的问题: 在libC中定义了数据结构(DS1),但是在libC1和libC2中,数据结构略有不同。

    编译器/链接器/程序如何确定它们将使用哪种版本的数据结构?

2 个答案:

答案 0 :(得分:0)

如果libC1libC2中的结构定义不同,那么它肯定会在某个地方访问错误的偏移量。它未定义的行为。我们不应该这样使用。

答案 1 :(得分:0)

数据结构不是对象,因此链接器不会直接看到它们。每个库都将采用它们的布局。

如果不在不同版本之间共享数据结构的实际实例,则此方法可以正常工作。例如,在您的场景中,只要在fwA和libB之间没有传递此类结构,您就可以了。 fwA和libC1之间的通信是安全的,libB和libC2也是如此。

Windows世界始终这样做:每个调用mallocfree的DLL都将链接到特定版本的C运行时,甚至可能使用内联函数来访问分配器数据结构。

只要分配了对象的DLL也负责释放它,这是完全可以接受的。因此,如果你的图书馆有

foo *alloc_foo() { return (foo *)malloc(sizeof(foo)); }

然后在收到的指针上调用free(my_foo);是不安全的,因为DLL可能正在使用不同的分配器实现。相反,使用他们提供的

void free_foo(foo *fp) { free(fp); }

因此,应该设计fwA和libB之间的接口,使其不依赖于libC ABI,否则libC ABI也会成为libB ABI的一部分。