我有一个正在使用FreeImage和openCV的项目,目前我们正在使用这两个方面的jpeg支持(我正在努力解决这个问题,但是现在它必须留下来)。无论如何,FreeImage将libjpeg 7.0编译成静态库,而openCV的highgui库将它作为共享库链接(在我的系统上,Ubuntu 9,我安装了libjpeg 6.2)。
它们链接到一个用于链接到各种程序,java包装器等的最终库。所有这些工作正常,在编译/链接时没有符号冲突或任何事情。但是,当我使用openCV cvLoadImage函数打开图像时,它会在读取标题时死亡,这很可能是由于6.2和7.0中标题之间的差异造成的。
如果我取消链接FreeImage(并注释掉需要它的代码),openCV调用将再次开始工作,因此FreeImage中的静态libjpeg符号与将从libjpeg共享库加载的符号相冲突。我无法弄清楚的是为什么我的编译器在链接期间没有抛出错误,因为有两组libjpeg符号。另外,我已经尝试用7.0版本暂时替换我的系统的jpeglib.h头文件,看看openCV编译后是否会与freeimage带来的符号同步,似乎无济于事。
最后,我将一个printf放在libjpeg的jpeg_read_header中,即freeimage编译,并重建它以查看openCV是否正在使用freeimage libjpeg定义。它没有打印出来所以我不得不假设。
所以我想我的问题是
1)为什么不链接静态libjpeg和共享libjpeg会因重复符号而产生链接错误?
2)有谁知道为什么这两件事彼此冲突?
编辑:在调试模式下编译openCV然后再次以常规模式编译似乎已经松动了一些东西并使其再次工作,不知道发生了什么。
答案 0 :(得分:2)
您需要修改链接选项以仅导出所需的符号,然后冲突中的所有符号将在内部隐藏在静态链接中,然后不会发生冲突。默认情况下,所有符号都会导出,这就是问题所在。请看这个链接:http://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html
答案 1 :(得分:1)
就像这样
编译静态库,动态库在运行时加载,但只有那些缺失的符号(我认为)。你可以编译共享库,然后你可能会遇到符号冲突。
所以opencv使用编译的符号,因为它们已经存在,而不是动态库中的符号。从opencv的角度来看,你最终会使用静态符号,可能有不同的签名。
答案 2 :(得分:1)
一般来说,链接器可以通过多个库来解决相同的符号。它只使用它找到的第一个。链接器命令行上的库的顺序将决定哪一个“获胜”。
顺便说一下,这不是对象文件。我曾经使用的每个链接器都假定您想要使用您指定的所有对象,并且如果多个具有相同的符号,则会抱怨。