在为服务器编写共享库时,我遇到了以下情况。
为了便于理解:
fwA通过dllopen加载libB
以下是我的问题: 在libC中定义了数据结构(DS1),但是在libC1和libC2中,数据结构略有不同。
编译器/链接器/程序如何确定它们将使用哪种版本的数据结构?
答案 0 :(得分:0)
如果libC1
和libC2
中的结构定义不同,那么它肯定会在某个地方访问错误的偏移量。它未定义的行为。我们不应该这样使用。
答案 1 :(得分:0)
数据结构不是对象,因此链接器不会直接看到它们。每个库都将采用它们的布局。
如果不在不同版本之间共享数据结构的实际实例,则此方法可以正常工作。例如,在您的场景中,只要在fwA和libB之间没有传递此类结构,您就可以了。 fwA和libC1之间的通信是安全的,libB和libC2也是如此。
Windows世界始终这样做:每个调用malloc
和free
的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的一部分。