Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Linux gcc链接问题_C++_C - Fatal编程技术网

C++ Linux gcc链接问题

C++ Linux gcc链接问题,c++,c,C++,C,我有两个库,分别名为lib1和lib2,它们彼此不依赖。我无法控制这些库是如何构建的。当我尝试链接它们时,链接的顺序决定了最终可执行文件中的不同行为 例如: 如果我将它们链接为[1] gcc $(CC_FLAGS) -o app.out -llib1 -llib2 一切正常 但是,如果我将它们链接如下[2] gcc $(CC_FLAGS) -o app.out -llib2 -llib1 可执行文件运行期间发生分段错误 任何有关此问题原因的建议或指针都会有所帮助 更新: 这两个库都依赖于

我有两个库,分别名为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]编译lib1,则segfault发生在lib1上,如果使用上面的选项[2]编译lib2,则异常发生在lib2上

更新2

该问题是由于库之间的全局命名空间冲突造成的。由于thrift使用IDL机制生成源文件,所以两个库都以某种方式为其IDL定义定义了相同的名称空间,因此观察到了这种行为。接受以下正确答案,因为它间接地解决了问题


谢谢。

这两个LIB中是否都有相同名称的符号

链接器将使用哪一个来解析这种符号的用法取决于顺序不确定我在哪里读过这篇文章

提示:这只是一个猜测

假设lib1定义了这个函数:

void foo int,char*; lib2定义了:

void foo int; 在某个地方我们有这样一个电话:

foo( 42 );
现在,如果链接器找到lib1的定义,这个foo很可能会得到有趣的垃圾作为它的第二个参数

更新对问题截止日期的反应 用我们的洞察力很难做出准确的陈述。所以我只能指出一些猜测,希望它们能帮助你。很抱歉我的错误。但我不知道我还能怎么继续:

猜测1:

更新说明:如果lib1使用上面的[1]选项编译,则segfault发生在lib1上;如果lib2使用[2]选项编译,则异常发生在lib2上

lib1中的ABI不兼容异常处理?什么样的

猜2或者我应该给它命名为故事:


我们的代码继承并实现了在thrift头中声明的抽象类。然后,通过执行对该impl的调用的冲突符号,将该impl传递给lib1/lib2。但是lib1在编译过程中使用了不同的thrift头,或者使用了条件编译,或者使用了另一个版本的thrift。

这两个lib中是否都存在相同名称的符号

链接器将使用哪一个来解析这种符号的用法取决于顺序不确定我在哪里读过这篇文章

提示:这只是一个猜测

假设lib1定义了这个函数:

void foo int,char*; lib2定义了:

void foo int; 在某个地方我们有这样一个电话:

foo( 42 );
现在,如果链接器找到lib1的定义,这个foo很可能会得到有趣的垃圾作为它的第二个参数

更新对问题截止日期的反应 用我们的洞察力很难做出准确的陈述。所以我只能指出一些猜测,希望它们能帮助你。很抱歉我的错误。但我不知道我还能怎么继续:

猜测1:

更新说明:如果lib1使用上面的[1]选项编译,则segfault发生在lib1上;如果lib2使用[2]选项编译,则异常发生在lib2上

lib1中的ABI不兼容异常处理?什么样的

猜2或者我应该给它命名为故事:


我们的代码继承并实现了在thrift头中声明的抽象类。然后,通过执行对该impl的调用的冲突符号,将该impl传递给lib1/lib2。但是lib1在编译期间使用了不同的thrift头,或者使用了条件编译,或者使用了另一个版本的thrift。

库的顺序很重要。这回答了你的问题吗@zgyarmati:这些答案解释了为什么你可能会出现链接器错误,但我不知道为什么你会在运行时出现崩溃。我的错,请澄清一下。你有没有像其他人一样尝试过调查segfault?这可能是一个令人厌烦的旧内存错误、缓冲区溢出等,这恰好取决于内存的精确布局。库的顺序很重要。这回答了你的问题吗@zgyarmati:这些答案解释了为什么你可能会出现链接器错误,但我不知道为什么你会在运行时出现崩溃。我的错,请澄清一下。你有没有像其他人一样尝试过调查segfault?这可能是一个无聊的旧内存错误缓冲区溢出等,恰好取决于内存的精确布局。已验证这可能发生在动态库中。很好的捕获,在这种情况下,它类似于定义TRUE FALSE//Happy调试混蛋:@NateEldredge两个库都被拉入,链接应该会失败,并出现有关多重定义的错误。与共享库不同,l
inker只会注意到符号在按顺序检查库时存在。如果你做一个ldd。。。在生成的可执行文件上,您将看到加载共享对象的顺序。通常,第一个加载了匹配符号的库将获胜。匹配只通过符号名进行,因此foo int将匹配foo char*甚至foo uint64_t*数组。感谢您的捕获,显然这两个库都依赖于另一个动态库Apache thrift,这个问题似乎与thrift库加载有关。还有其他人在apache thrift中遇到过这种情况吗?验证了这种情况在动态库中可能发生。很好,在这种情况下,它类似于定义TRUE FALSE//Happy debugging bastards:@NateEldredge两个库都被拉入,链接应该会因多个定义的错误而失败。与共享库不同,链接器在按顺序检查库时只会注意到符号存在。如果你做一个ldd。。。在生成的可执行文件上,您将看到加载共享对象的顺序。通常,第一个加载了匹配符号的库将获胜。匹配只通过符号名进行,因此foo int将匹配foo char*甚至foo uint64_t*数组。感谢您的捕获,显然这两个库都依赖于另一个动态库Apache thrift,这个问题似乎与thrift库加载有关。还有其他人在apache thrift中经历过这种情况吗?