0
votes

I want to call C++ code from java using JNI. I already followed many tutorials on this, and all are working, when the C++ code is "simple". But the C++ code which I am going to call inludes the opencv library and uses various functions of it. And this is, where I get problems... What I am doing is the following:

1.) g++ -fPIC -shared -I/usr/lib/jvm/java-1.7.0-openjdk-i386/include -I/usr/lib/jvm/java-1.7.0-openjdk-i386/include/linux -o libHello.so Hello.cpp

which creates the .so file.

2.) I copy my created .so file to the directory where I use it, just as I did with the tutorials, and load it:

static {
        System.loadLibrary("Hello");
       }

But I get an UnSatisfiedLinkError with undefined symbol: _ZTTN2cv4SURFE

Most probably there is an error in the first step, such that it can not find my opencv library. But I don't know what the correct command would be.

ldd -d libHello.so produces:

linux-gate.so.1 =>  (0xb777d000)
libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0xb765e000)
libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb7640000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7496000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb746a000)
/lib/ld-linux.so.2 (0xb777e000)

undefined symbol: _ZTTN2cv4SURFE (./libHello.so)

undefined symbol: _ZTV11CvStatModel (./libHello.so)

undefined symbol: _ZTVN2cv24BackgroundSubtractorMOG2E (./libHello.so)

undefined symbol: _ZTVN2cv4SURFE (./libHello.so)

undefined symbol: _ZTV5CvSVM (./libHello.so)

edit:

For anyone else getting the same problem:

1.) As some people mentioned, I was not linking against the opencv library.

2.) But this was not enough. I was using this command, as it is also done in some tutorials:

g++ -shared -I/usr/lib/jvm/java-1.7.0-openjdk-i386/include -I/usr/lib/jvm/java-1.7.0-openjdk-i386/include/linux -I/usr/local/include/opencv -L/usr/local/lib -lopencv_nonfree -lopencv_features2d -lopencv_core -lopencv_highgui Hello.cpp -o libHello.so

which caused the undefined symbol error when doing "ldd"

I changed the command to:

g++ Hello.cpp -shared -I/usr/lib/jvm/java-1.7.0-openjdk-i386/include -I/usr/lib/jvm/java-1.7.0-openjdk-i386/include/linux -I/usr/local/include/opencv -L/usr/local/lib -lopencv_nonfree -lopencv_features2d -lopencv_core -lopencv_highgui -o libHello.so

i.e. I just wrote Hello.cpp directly after g++ instead at the end. And this solved the problem.

I don't know why this is working and the previos one didn't. But maybe someone can tell me.

1
c++filt tells me that first symbol is VTT for cv::SURF.Joe Z
you're not linking your hello.so against the opencv libsberak
berak, this is most probably the problem... But how would I do that?user3119455
@berak i tried it this way: g++ -shared -I/usr/lib/jvm/java-1.7.0-openjdk-i386/include -I/usr/lib/jvm/java-1.7.0-openjdk-i386/include/linux -I/home/name/opencv-2.4.6.1/lib -lopencv_nonfree -lopencv_features2d -lopencv_core -lopencv_highgui Hello.cpp -o libHello.so It's still the same, doesn't this link the libraries correctly?user3119455
still not enuogh, BackgroundSubtractorMOG2 is in opencv_video, SVM is in opencv_ml, SURF is in opencv_nonfreeberak

1 Answers

0
votes

You may need to specify a path to your additional libraries so the JVM can load them. Add an argument to Java:

-Djava.library.path=/path/to/opencv/libs:/other/paths/as/needed

This argument must come before your class name so that Java knows it is an argument for the JVM and not for your program.