Writing, Compiling, and Linking The C Function
For convenience, I'm putting the
We need to #include <stdio.h> #include "HelloWorld.h" JNIEXPORT void JNICALL Java_example_jni_HelloWorld_writeHelloWorldToStdout(JNIEnv *env, jclass c) { printf("Hello World!"); }
Now, we need to compile and link this example into a DLL. You can do this directly with gcc -mno-cygwin -I$jdk/include -I$jdk/include/win32 -Wl,--add-stdcall-alias -shared -o HelloWorld.dll HelloWorld.cCompiling with the -mno-cygwin option enables us to build DLL files which are not dependent upon the Cygwin
DLL (and thus cannot make use of its APIs). We have specified two include directories from the JDK distribution, which
bring in jni.h (which is at the top of our generated header file). The -shared option causes
the compiler to generate a DLL rather than an executable. The -Wl,-add-stdcall-alias passes the
--add-stdcall-alias option to
the linker.
Chuck Wilson was nice enough to let me know that I needed it; an UnsatisfiedLinkError results
without it. The man page for ld says:
--add-stdcall-alias If given, symbols with a stdcall suffix (@nn) will be exported as-is and also with the suffix stripped.... if that's helpful to you. Essentially (again, according to Chuck) this option causes gcc to emit
DLLs which contain symbols both for the C calling convention and the Pascal calling convention (Windows normally uses
the Pascal calling convention for DLL invocations, and so java.exe apparently does as well).
If you get an error like HelloWorld.c:1:19: stdio.h: No such file or directory(followed by a bunch of other errors from the JNI header files), it probably means that you are missing the gcc-mingw or
mingw-runtime packages.
These packages provide the headers and libraries necessary to compile Win32 programs using gcc ;
they support the -mno-cygwin option on Cygwin. You'll
need to run the Cygwin setup program and install these packages. (They're
both under the "Devel" category, among other places, in the tree.)
If you get something like: /usr/lib/gcc-lib/i686-pc-mingw32/3.2/../../../../i686-pc-mingw32/bin/ld: cannot find -luser32it probably means that you are missing the w32api package, which is available as part of the "Libs" category
in the tree.
|