I’m preparing everything I need to know for this project when coding time officially starts. I’m now at the point when I have to learn how to do Java bindings for C++. I have created class that contains native methods.
[java]
package some;
public class NativeMethods {
// Declare a native method sayHello() that receives nothing and returns void
public native void sayHello();
// Declare a native method sayNumber() that receives a number and returns void
public native void sayNumber(int number);
// Declare a native method sayMyName() that receives a string and returns void
public native void sayMyName(String name);
}
[/java]
I have build it, and then when I used command javah NativeMethods.class (I went to where NativeMethods.class is, so there is no path trouble…), there is this error:
[java]
Exception in thread “main” java.lang.IllegalArgumentException: Not a valid class name: NativeMethods.class
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:177)
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:68)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:509)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:335)
at com.sun.tools.javah.Main.main(Main.java:46)
[/java]
I tried looking for solutions online, but none of them were helpful. Does anybody have some idea?
@Tihomir said:
I have build it, and then when I used command javah NativeMethods.class (I went to where NativeMethods.class is, so there is no path trouble...), there is this error:
I don’t think javah works this way. It needs a “fully qualified class name” according to the docs. You can’t just change to the same directory as the class and run it. It takes a class argument the same way javap and java.exe do and is based on the classpath.
That helped a lot, but there were some troubles, but for the phase of generating C header command
[java]javah -classpath ~/NetBeansProjects/JavaNativeInterface/build/classes -o HelloNative.h some.NativeMethods
[/java] did the work perfectly.
Note: these should really probably be part of a build and not manually run from the command line. And in that case, the build support for javah, etc. will probably wire some stuff up for you.
I don’t know. I haven’t done any C programming in years and years and years… but I still know there is a difference between -include and -I (capital i)… one takes a file and the other takes a directory. And in your case you are passing a directory as a file.
I found how to to set in NetBeans when it compiles to use -I instead -include, but that didn’t work:
[java]"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory /home/tihomir/NetBeansProjects/JNIDemoCdl' "/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/libJNIdemoCdl.so make[2]: Entering directory /home/tihomir/NetBeansProjects/JNIDemoCdl’
mkdir -p build/Debug/GNU-Linux-x86
rm -f “build/Debug/GNU-Linux-x86/JNIDemo.o.d”
gcc -m32 -shared -m32 -c -g -I/usr/lib/jvm/java-7-oracle/include -fPIC -MMD -MP -MF “build/Debug/GNU-Linux-x86/JNIDemo.o.d” -o build/Debug/GNU-Linux-x86/JNIDemo.o JNIDemo.c
In file included from /usr/include/stdio.h:28:0,
from /usr/lib/jvm/java-7-oracle/include/jni.h:39,
from JNIDemo.c:1:
/usr/include/features.h:324:26: fatal error: bits/predefs.h: No such file or directory
compilation terminated.
make[2]: *** [build/Debug/GNU-Linux-x86/JNIDemo.o] Error 1
make[2]: Leaving directory /home/tihomir/NetBeansProjects/JNIDemoCdl' make[1]: *** [.build-conf] Error 2 make[1]: Leaving directory /home/tihomir/NetBeansProjects/JNIDemoCdl’
make: *** [.build-impl] Error 2[/java]
It didn’t work when I added -include and -I option, then the error was the same as previous.
Btw if you need some more examples, take a look at the bullet binding, and (for easier understanding of the steps) the older ant based build for it.
There are some things thats important to keep in mind.
-> the more or less reflective c access is expensive to lookup but check to invoke, kinda like with normal reflection getting the metadata stuff is the costly.
-> Some stuff gets garbagecollected on the native side, and you need to explicitly make a reference for it, to prevent that.
-> Some stuff is only valid in a single call context, if you use it outside/in the next call it contains garbage/corrupted data
@Empire Phoenix said:
Btw if you need some more examples, take a look at the bullet binding, and (for easier understanding of the steps) the older ant based build for it.
I meant to ask if there is CSV repository of bullet binding. I think it could be very educational for me to see how the process went from beginning to the end.