As my first technical post, I'm going to overview how to use JNI with C++.
My platform:Windows Vista Ultimate
AMD Athlon64 X2 6000+
5GB DDR2
Java 1.6.0_06 64-bit
Microsoft Visual Studio 2008
Straight to the code:[HelloWorld.java]
class HelloWorld {
public static native void HelloNative(String s);
static {
System.loadLibrary("HelloDLL");
}
public static void main(String[] Args){
HelloNative("Hello, world!");
}
}
Things to note:- The method we're going to create in the DLL is declared as "native" but not defined.- To load the methods from the DLL, we call System.loadLibrary("library");- Do not put the extension in the call - our DLL will be HelloDLL.dll, so we call with "HelloDLL"- After that, we can use the function just as normal.[HelloWorld.cpp (here's where it gets messy)]
#include "HelloWorld.h"
JNIEXPORT void JNICALL Java_HelloWorld_HelloNative(JNIEnv *env, jobject obj, jstring javaString){
const char *input = env->GetStringUTFChars(javaString, 0);
printf("%s\n", input);
env->ReleaseStringUTFChars(javaString, input);
}
Things to note:-The header "HelloWorld.h" will be generated by javah as we'll see in a bit.-The function name must be Java_ClassName_MethodName-The function parameters must start with a JNIEnv* and a jobject, after that come your own.-To use the jstring you passed in as a character array, you have to call GetStringUTFChars-You MUST call ReleaseStringUTFChars after calling GetStringUTFChars once you're donePutting it all together:
javac HelloWorld.java
javah -jni HelloWorld
[Here you can use a C++ compiler of your choice, as long as you know how to use it to create a DLL. This example is with Visual Studio 2008]
call "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" amd64
cl -I"c:\program files\java\jdk1.6.0_06\include" -I"c:\program files\java\jdk1.6.0_06\include\win32" -I"." -MT -LD HelloWorld.cpp -FeHelloDLL.dll
All done!Let's go over the compilation.
You'd better know what javac does already; javah creates the header file for the class, which we already included in our cpp file (HelloWorld.h).
The first Visual Studio command is a batch file, with an architecture parameter. I'm compiling to amd64. The batch file sets the paths and settings necessary for compilation, makes things easy. I don't believe the standard install of Visual Studio comes with the different architectures - you have to enable it during install (you can go to reinstall and add it without reinstalling the whole thing). Visual Studio Express may not have it - you'll have to install the Windows SDK to get them. There's a help page on the MSDN somewhere about that.
cl is the command-line compiler for Visual Studio. I'm adding include paths to Java's includes directories, as well as the current directory. Some extra switches for good measure, the source file, and the output file.
Viola! You now have your DLL.
Important Note:With Visual Studio, you can either compile with -MT or -MD. I believe default is MD. the difference is that MT adds the library code directly (statically) to your DLL, while MD links it dynamically. If you use MD, your program is now dependent on msvcr90.dll (or whatever version of Visual Studio you're using). If it fails to run, you need to grab this DLL. I chose to just put it in with my own DLL, as not everyone is going to have it. If you don't, you can find it easily online, or if you have Visual Studio it should be at:
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\somewheredownthereI prefer to use MT, so that I don't have to worry about distributing extra static libraries. There are up and downsides to using both. Static will make your DLL a little larger, will MD will make your DLL rely on other libraries. You also may have to embed the manifest file into your DLL if you use MD.
Also note that there are different versions of msvcr90.dll for different architectures, if you choose to use dynamic linking. You can't use the wrong one. Don't worry, it should tell you if you have the wrong one.
Anyway...
That's the end of my first post. Hope you enjoyed.