yby
yby

Reputation: 915

Java program that access C++ shared library that uses OpenCV

We developed a C++ shared library (libAuxLinuxShared.so), that uses OpenCV 2.4

We also developed a command-line Java app that access libAuxLinuxShared.so via JNI. This app is deployed in Ubuntu 14.10

When running the Java app, we're getting the following result:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /vagrant/Milan/Linux/libAuxLinuxShared.so: /vagrant/Milan/Linux/libAuxLinuxShared.so: undefined symbol: _ZTVN2cv12_OutputArrayE
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1122)
    at com.mi.pixme.PixmeJavaAPI.<clinit>(PixmeJavaAPI.java:8)
    at com.mi.pixme.PixmeCommandRunner.main(PixmeCommandRunner.java:11)

It appears to me that OpenCV is not linked properly when making libAuxLinuxShared.so, or that the OpenCV shared libraries cannot be found. I'm not a C++ expert, certainly not under Linux, and I'm not sure what to do next.

Some more details

I tried to do this in two ways:

  1. Make OpenCV as shared libraries

  2. Make OpenCV as static libraries, and try to link libAuxLinuxShared.so with them (with -l). I use pkg-config --libs --cflags opencv in the Makefile in order to get the complete list of libraries.

In both cases I get the same result.

It may be helpful to note that the result of:

$ nm -D libAuxLinuxShared.so | grep _ZTVN2cv12_OutputArrayE

Is:

U _ZTVN2cv12_OutputArrayE

even when I try to do static linking of OpenCV. The symbol is probably defined in the opencv_core library:

$ nm /usr/local/lib/libopencv_core.so | grep _ZTVN2cv12_OutputArrayE
00000000004b1de0 V _ZTVN2cv12_OutputArrayE

I also tried setting LD_LIBRARY_PATH=/usr/local/lib:/usr/local/share/OpenCV/3rdparty/lib (which is where the OpenCV libs are located), but the result was the same. One last thing I tried was to load the opencv_core shared libary (where I think _ZTVN2cv12_OutputArrayE is located) from the Java app:

  1. Added to the Java main class:

    System.loadLibrary("opencv_core");

  2. And then adding /usr/local/lib to the library path of the Java command, like this:

    -Djava.library.path=/usr/local/lib:.

But again, same results. I can see that the Java program finds the library, because if I change opencv_core to some name that doesn't exist, I get a different error (that the library can't be found). But when the library name is correct, it has no effect on the results, which is the exception complaining the _ZTVN2cv12_OutputArrayE is not defined.

Edit: The following gist contain the makefiles I use for building the shared library: https://gist.github.com/yanivby/69984a541e97e33d815a76a9bbf4d712

Upvotes: 0

Views: 424

Answers (1)

Yam Marcovic
Yam Marcovic

Reputation: 8141

According to the Makefiles in your gist, the problem seems to be that the pkg-config --libs --cflags opencv, which adds a bunch of -l library arguments to the linker, is mentioned before the objects that actually depend on those libraries. In your Makefile, the easiest fix would be to move your $(INCLUDES) reference to the end of the commands, after $(LIBS).

Upvotes: 2

Related Questions