我有两个库,名为(lib1和lib2),两者都不相互依赖。我无法控制这些库的构建方式。当我尝试链接它们时,链接的顺序决定了最终可执行文件中的不同行为,
例如:
如果我将其链接为[1]
gcc $(CC_FLAGS) -o app.out -llib1 -llib2
一切正常但是,如果我将它们链接如下[2]
gcc $(CC_FLAGS) -o app.out -llib2 -llib1
可执行程序运行期间发生分段错误。关于此问题的成因的任何建议或指示都将有所帮助。
更新:
这两个库都依赖于另一个动态库,即Apache Thrift(版本0.11.0),如果在上面编译了[1]选项,segfault就会在lib1上发生,如果在上面编译了上述选项[2]的话,lib2上就会发生异常。
更新2
该问题是由于库之间的全局 namespace 冲突引起的。由于thrift使用IDL机制生成源文件,因此两个库(都以某种方式)为其IDL定义定义了相同的 namespace ,因此观察到了这种行为。接受以下答案是正确的答案,因为它间接解决了这个问题。
谢谢。
最佳答案
这两个库中是否可能都存在一个符号(名称相同)?
链接器将使用哪一个来解析此类符号的使用,具体取决于顺序(不确定在哪里阅读)。
(提示:这只是一个猜测)
因此,假设lib1定义了此功能:
void foo( int, char* );
lib2定义:void foo( int );
在某个地方,我们有一个像这样的电话:foo( 42 );
现在,如果链接器找到lib1的定义,则此foo最有可能将获得有趣的垃圾作为其第二个参数。更新(对问题的最新反应)
用我们的见识很难做出准确的陈述。因此,我只能指出一些猜测,希望它们能为您提供帮助。非常抱歉我在这里的不准确。但我不知道该如何继续:
猜1 :
更新说:“如果在上面编译了[1]选项,则lib1上会发生段错误;如果在上面使用选项[2]编译,则lib2上会发生异常”
lib1中的ABI不兼容异常处理?像this一样?
Guess 2 (或者我应该将其命名为“故事”):
我们的代码继承(并实现)在Thrift header 中声明的抽象类。然后,将该impl传递给lib1 / lib2(通过我们有冲突的符号),该lib1 / lib2执行对该impl的调用。但是lib1在编译过程中使用了不同的Thrift header (或使用了条件编译,或使用了Thrift的另一个版本)。