Static and shared library symbol conflicts?
I've got a project working on that's using FreeImage and openCV, currently we're using the jpeg support from both of these (I am working towards fixing t开发者_C百科hat, but for now it's got to stay). Anyhow, FreeImage compiles libjpeg 7.0 into its static libraries, and openCV's highgui library links it in as a shared library (on my system, Ubuntu 9, I've got libjpeg 6.2 installed).
They link into a final library that's used to link into various programs, java wrappers, etc. All of that works fine, no symbol conflicts or anything during compile/link time. However, when I go to open an image using the openCV cvLoadImage function, it dies when reading the header, most likely due to differences between headers in 6.2 and 7.0.
If I unlink FreeImage (and comment out the code that requires it), the openCV calls start working again, so clearly the static libjpeg symbols from FreeImage are conflicting with symbols that would be loaded from the libjpeg shared library. What I can't figure out is why my compiler isn't throwing an error during linking because of the two sets of libjpeg symbols. Additionally, I've tried replacing my system's jpeglib.h header with the 7.0 version temporarily to see if openCV compiled with that would then sync up with the symbols that freeimage brings to the table, to no avail it seems.
Lastly I put a printf in jpeg_read_header in the libjpeg that freeimage compiles, and rebuilt it to see if openCV is using the freeimage libjpeg definition. It didn't print out so I have to assume not.
So I guess my questions are
1) Why doesn't linking a static libjpeg and a shared libjpeg generate linking errors due to duplicate symbols?
2) Does anyone know why these two things are conflicting with one another?
Edit: Compiling openCV in debug mode and then in regular mode again seems to have knocked something loose and made it work again, no idea what's going on.
Generally speaking the linker is fine about being passed multiple libraries that all resolve the same symbol(s). It just uses the first one it finds. The order of the libraries on your linker command line will determine which one "wins".
This, by the way, is NOT true of object files. Every linker I've ever used assumes that you want to use all of the objects that you specify, and will complain if more than one has the same symbol.
You need to modify the linking options to export only the symbols that you want, then all the symbols in conflict will be hidden internally in the static linking, then no conflicts. By default all the symbols are exported, that's the problem. See this link: http://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html
it is like this
Static libraries are compiled in, dynamic libraries are loaded during runtime, but only those symbols which are missing (I think). you can compile shared libraries in, and then you probably get symbol collision.
so opencv uses symbols which are compiled in, since they already present, rather than those from dynamic libraries. you end up using static symbols, possibly with different signatures, from prospective of opencv.
精彩评论