Calling C from Java - passing an
int
Suppose we want to implement the method
int toDouble(int) in C, instead of Java. The
steps required are:
- Declare a native Java method with the desired signature
(line 5)
- Add a static initialization block to the Java class (lines 6-8)
- Use javac to produce a .class file
- Use javah to produce a C header file (lines 16-34)
- Copy the C function signature from the C header file into a C source file
(line 39)
- #include the generated C header file in the C source file
(line 37)
- Implement the body of the C function (lines 40-41)
- Compile the C source file into a .dll
- Use java to run the .class file (line 44)
Step 2 above is required because Java expects a dynamic link library to
be available when the native method is invoked. This is set-up by
calling System.loadLibrary() and passing it the name of a
.dll file (line 7). We can ensure that this happens prior to the first
use of the Java class that contains the native method by placing the
call in a static initialization block.
Rather than generate the cryptic C function name and signature by hand,
it is a lot easier to have Java do it. The command for step 4 is
javah JNIdemos
If javah has a problem, make sure the
CLASSPATH environment variable includes the currect
directory. Notice that:
- the name of the header file is the argument specified in the
System.loadLibrary() call,
- the name of the C function is mangled from the name of the Java
native method, and
- the argument list of the C function has had two extra parameters prepended
The command for step 8 is
cl -LD JNIdemos.cpp -FeJNIdemos.dll /ML
Notice how the single int parameter to the native method
(line 5) has been mapped to the third parameter of the C function (line
39). Its type is jint, which is defined in
jni.h (included at line 18 via line 37). The return value
is also of type jint.
The first two parameters defined for the C function are not required in this
example.
[source: Horstmann98, pp581-588]