JavaCPP Example

802 views
Skip to first unread message

Jotschi

unread,
Aug 26, 2011, 7:00:20 AM8/26/11
to javacpp
Hi,

i'm trying to get a very basic example up and running. But i have some
trouble with compiling the jni sources.

jotschi@Amilo:~/workspace/JavaCPPTest$ java -jar libs/javacpp.jar -
properties linux-x86 -classpath bin -Dcompiler.includepath=/home/
jotschi/workspace/JavaCPPTest/jni/ NativeCube
Generating source file: /home/jotschi/workspace/JavaCPPTest/bin/
jniNativeCube.cpp
Building library file: /home/jotschi/workspace/JavaCPPTest/bin/linux-
x86/libjniNativeCube.so
g++ -I/usr/lib/jvm/java-6-sun-1.6.0.26/include -I/usr/lib/jvm/java-6-
sun-1.6.0.26/include/linux -I/home/jotschi/workspace/JavaCPPTest/jni/ /
home/jotschi/workspace/JavaCPPTest/bin/jniNativeCube.cpp -march=i686 -
m32 -Wall -O3 -fPIC -shared -s -o /home/jotschi/workspace/JavaCPPTest/
bin/linux-x86/libjniNativeCube.so
/home/jotschi/workspace/JavaCPPTest/bin/jniNativeCube.cpp: In function
‘void Java_NativeCube_Cube(JNIEnv*, _jobject*)’:
/home/jotschi/workspace/JavaCPPTest/bin/jniNativeCube.cpp:720: error:
expected primary-expression before ‘*’ token
/home/jotschi/workspace/JavaCPPTest/bin/jniNativeCube.cpp:720: error:
‘pointer’ was not declared in this scope
/home/jotschi/workspace/JavaCPPTest/bin/jniNativeCube.cpp:720: error:
expected primary-expression before ‘*’ token
/home/jotschi/workspace/JavaCPPTest/bin/jniNativeCube.cpp:720: error:
expected primary-expression before ‘)’ token
....

The sources i used can be viewed here: https://gist.github.com/1173186
I use JavaCPP Build 20110705
I tested the cube cpp implementation with a small cpp program.
Compiles just fine. And JNIEnv is defined within the jni.h which can
be found. The error must be related to the _jobject* pointer but i
have no idea whats wrong with it.

Any clue what i'm doing wrong here?

The given vector example works just fine. Even on Android ;)

Greetings,

Jotschi

Samuel Audet

unread,
Aug 27, 2011, 3:24:00 AM8/27/11
to javacpp...@googlegroups.com
Hello,

We need to map C++ classes as static Java classes that extend
com.googlecode.javacpp.Pointer inside a top level class. Check this file
for simple examples of that:
http://code.google.com/p/javacv/source/browse/trunk/javacv/src/com/googlecode/javacv/cpp/ARToolKitPlus.java
And we need to declare allocate() methods that are mapped to the C++
constructors...

Let me know if something isn't clear, thanks

Samuel

On 2011-08-26 20:00, Jotschi wrote:
> Hi,
>
> i'm trying to get a very basic example up and running. But i have some
> trouble with compiling the jni sources.
>
> jotschi@Amilo:~/workspace/JavaCPPTest$ java -jar libs/javacpp.jar -
> properties linux-x86 -classpath bin -Dcompiler.includepath=/home/
> jotschi/workspace/JavaCPPTest/jni/ NativeCube
> Generating source file: /home/jotschi/workspace/JavaCPPTest/bin/
> jniNativeCube.cpp
> Building library file: /home/jotschi/workspace/JavaCPPTest/bin/linux-
> x86/libjniNativeCube.so
> g++ -I/usr/lib/jvm/java-6-sun-1.6.0.26/include -I/usr/lib/jvm/java-6-
> sun-1.6.0.26/include/linux -I/home/jotschi/workspace/JavaCPPTest/jni/ /
> home/jotschi/workspace/JavaCPPTest/bin/jniNativeCube.cpp -march=i686 -
> m32 -Wall -O3 -fPIC -shared -s -o /home/jotschi/workspace/JavaCPPTest/
> bin/linux-x86/libjniNativeCube.so
> /home/jotschi/workspace/JavaCPPTest/bin/jniNativeCube.cpp: In function

> �void Java_NativeCube_Cube(JNIEnv*, _jobject*)�:
> /home/jotschi/workspace/JavaCPPTest/bin/jniNativeCube.cpp:720: error:
> expected primary-expression before �*� token
> /home/jotschi/workspace/JavaCPPTest/bin/jniNativeCube.cpp:720: error:
> �pointer� was not declared in this scope
> /home/jotschi/workspace/JavaCPPTest/bin/jniNativeCube.cpp:720: error:
> expected primary-expression before �*� token
> /home/jotschi/workspace/JavaCPPTest/bin/jniNativeCube.cpp:720: error:
> expected primary-expression before �)� token

Johannes Schüth

unread,
Aug 27, 2011, 6:46:24 PM8/27/11
to javacpp...@googlegroups.com
Hello,

still got one problem:
jotschi@NeXuS:~/workspace/JavaCPPTest/jni$ make javacpp
java -jar ../libs/javacpp.jar -classpath ../bin -properties linux-x86 -Dcompiler.includepath=. JavaCube 
Generating source file: /home/jotschi/workspace/JavaCPPTest/bin/jniJavaCube.cpp
Building library file: /home/jotschi/workspace/JavaCPPTest/bin/linux-x86/libjniJavaCube.so
g++ -I/usr/lib/jvm/java-6-sun-1.6.0.26/include -I/usr/lib/jvm/java-6-sun-1.6.0.26/include/linux -I./. /home/jotschi/workspace/JavaCPPTest/bin/jniJavaCube.cpp -march=i686 -m32 -Wall -O3 -fPIC -shared -s -o /home/jotschi/workspace/JavaCPPTest/bin/linux-x86/libjniJavaCube.so 
/home/jotschi/workspace/JavaCPPTest/bin/jniJavaCube.cpp: In function ‘void Java_JavaCube_00024NativeCube_Cube(JNIEnv*, jobject)’:
/home/jotschi/workspace/JavaCPPTest/bin/jniJavaCube.cpp:742:18: error: invalid use of ‘Cube::Cube’
make: *** [javacpp] Error 1

I called the mapped native constructor of the Cube cpp class within my static java class. I'm not quite sure whether this is even supposed to work that way. How do i call the constructor? Is that even possible with JNI/Javacpp? You always call the allocate method in your example. I tried that but then i get a symbol lookup error (undefined symbol).


Greetings

Jotschi

Samuel Audet

unread,
Aug 27, 2011, 10:40:52 PM8/27/11
to javacpp...@googlegroups.com
On 2011-08-28 07:46, Johannes Sch�th wrote:
> I called the mapped native constructor of the Cube cpp class within my
> static java class. I'm not quite sure whether this is even supposed to
> work that way. How do i call the constructor? Is that even possible with
> JNI/Javacpp? You always call the allocate method in your example. I
> tried that but then i get a symbol lookup error (undefined symbol).

"native void allocate();" works just fine here.. What error do you get?

Samuel

Johannes Schüth

unread,
Aug 28, 2011, 7:12:14 AM8/28/11
to javacpp...@googlegroups.com, Samuel Audet
I get the following error if i try to execute the program:
/usr/lib/jvm/java-6-sun-1.6.0.26/bin/java: symbol lookup error:
/tmp/libjniJavaCube630002291116993195.so: undefined symbol: _ZN4CubeC1Ev

jotschi@NeXuS:~/workspace/JavaCPPTest/jni$ echo _ZN4CubeC1Ev | c++filt
Cube::Cube()

It can't find the constructor of my Cube class. I just copied the
libCube.so into bin/linux-x86

I did a strace:
jotschi@NeXuS:~/workspace/JavaCPPTest$ strace -f java -classpath
bin:libs/javacpp.jar
-Djava.library.path=/home/jotschi/workspace/JavaCPPTest/jni/ CubeTest

It looks to me that the jvm tries to find libCube methods/class within
/tmp/libjniJavaCube7947671323921108730.so


objdump -dr /tmp/libjniJavaCube3498489508158541705.so | c++filt | less

000015ac <Cube::Cube()@plt>:
15ac: ff a3 38 00 00 00 jmp *0x38(%ebx)
15b2: 68 58 00 00 00 push $0x58
15b7: e9 30 ff ff ff jmp 14ec <_init+0x30>

I don't know what @plt stands for but the libCube constructor signature
looks like this:
00000000 <Cube::Cube()>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 5d pop %ebp
4: c3 ret
5: 90 nop

Could that be the problem? Any ideas?


Jotschi

Samuel Audet

unread,
Aug 28, 2011, 7:19:36 AM8/28/11
to javacpp...@googlegroups.com
On 2011-08-28 20:12, Johannes Sch�th wrote:
> I get the following error if i try to execute the program:
> /usr/lib/jvm/java-6-sun-1.6.0.26/bin/java: symbol lookup error:
> /tmp/libjniJavaCube630002291116993195.so: undefined symbol: _ZN4CubeC1Ev

Strange, I get
Exception in thread "main" java.lang.NoSuchMethodError: main
which is perfectly normal given that there is no main() method...

It seems to me that you are trying to link the library using a C
compiler, in which case the C++ library isn't linked in by default and
you will get these unresolved symbols. Are you getting the same error
when you let JavaCPP compile/link the library for you? If so, what
platform and compiler?

Samuel

Samuel Audet

unread,
Aug 28, 2011, 7:26:39 AM8/28/11
to Johannes Schüth, javacpp...@googlegroups.com
On 2011-08-28 20:12, Johannes Sch�th wrote:
> I get the following error if i try to execute the program:
> /usr/lib/jvm/java-6-sun-1.6.0.26/bin/java: symbol lookup error:
> /tmp/libjniJavaCube630002291116993195.so: undefined symbol: _ZN4CubeC1Ev

Ah, I see what you are missing. Your constructor is defined in Cube.cpp,
so you either need to add this source file to the @Platform(include=...)
annotation, *or* you compile it yourself, and add it to the
@Platform(link=...) annotation, of the top level class.

Samuel

Johannes Schüth

unread,
Aug 28, 2011, 10:06:43 AM8/28/11
to javacpp...@googlegroups.com, Samuel Audet
Of course!

Did not thought about that :)

Now it works. I created a bundle with all sources which runs out of the box on linux x86


Jotschi

2011/8/28 Samuel Audet <samuel...@gmail.com>

Johannes Schüth

unread,
Aug 28, 2011, 10:11:08 AM8/28/11
to javacpp...@googlegroups.com, Samuel Audet
If you take a look at JavaCube.java you see that i use JavaCube as a wrapper for the NativeCube static class. Is that the supposed way to work with the static/native class?

Jotschi

Samuel Audet

unread,
Aug 28, 2011, 10:18:22 AM8/28/11
to Johannes Schüth, javacpp...@googlegroups.com
Great!

BTW, I like to use static nested classes and such because it makes the
source files more compact and similar looking to a C++ include file, but
we can also make the top level class extend Pointer directly, e.g.:
http://code.google.com/p/javacpp/source/browse/trunk/javacpp/src/com/googlecode/javacpp/SizeTPointer.java

> If you take a look at JavaCube.java you see that i use JavaCube as a wrapper for the NativeCube static class. Is that the supposed way to work with the static/native class?

If it compiles without complaining, then it's probably correct enough :)

Samuel

On 2011-08-28 23:06, Johannes Sch�th wrote:
> Of course!
>
> Did not thought about that :)
>
> Now it works. I created a bundle with all sources which runs out of the
> box on linux x86
>
> https://github.com/Jotschi/javacpp-examples
>
> Jotschi
>
> 2011/8/28 Samuel Audet <samuel...@gmail.com

> <mailto:samuel...@gmail.com>>

Reply all
Reply to author
Forward
0 new messages