As mentioned earlier in Chapter 2, one of the key goals of the KNI is to isolate the native function programmer from the implementation details of the virtual machine. Consequently, the KNI programmer should never include any VM-specific files into the files that implement native functions.
The file ‘kni.h
’ is a C header file that provides the declarations and definitions of all the data types exported by KNI as well as the prototypes of all the functions exported by KNI. When implementing native methods using KNI, this header file must always be included
This section shows a simple example that illustrates the use of KNI. We write a small Java class that calls a native (C) input/output function to print a message to standard output. We highlight the necessary steps that are required when writing new native functions. More comprehensive examples illustrating the use of KNI are provided in Chapter 7.
Below is a small Java application that defines a class named HelloWorld
contained in a package called mypackage
.
package mypackage; public class HelloWorld { public native void sayHello(); public static void main(String[] args) { new HelloWorld().sayHello(); } }
The HelloWorld
class definition contains two method declarations: a native method called sayHello
and a Java method called main
. When the application is run, the main
method creates an instance of the HelloWorld
class and invokes the native method sayHello
for this instance.
In this example, the native method sayHello
is implemented in a separate C programming language source file illustrated in the next subsection.
The function that implements the native method sayHello
must follow the function prototype definition specified in the header file that would be generated on invocation of javah
on the mypackage.HelloWorld
file. In this case, since the HelloWorld
application is contained in a package called mypackage
, the name of the native function must be as follows:
The mypackage.HelloWorld.sayHello
method is implemented in a C source file ’Java_mypackage_HelloWorld.c
’ as follows:
#include <kni.h> #include <stdio.h> KNIEXPORT KNI_RETURNTYPE_VOID Java_mypackage_HelloWorld_sayHello() { char* message = "hello, world!"; fprintf(stdout, "%s\n", message); KNI_ReturnVoid(); }
In this case, the implementation of the native function is very simple. It uses the standard C input/output function fprintf
to display the message “hello, world!”.
The C source file includes three header files:
kni.h
– This C header file provides the declarations and definitions of all the data types exported by KNI as well as the prototypes of all the functions exported by KNI. When implementing native methods, this C header file must always be included.stdio.h
– The code snippet above includes stdio.h
because it uses the standard C input/output function fprintf
.Below is a summary of the steps to run the sample KNI application in the KVM:
HelloWorld.java
shown above. In the simplest case, the Java class source file should reside in ‘${KVM_ROOT}/api/src/mypackage/HelloWorld.java
‘ so that the JavaCodeCompact tool can find, compile and romize the class automatically as part of the build process.Java_mypackage_HelloWorld.c
that implements the native method defined above. In this example, the C source file will reside in ‘${KVM_ROOT}/kvm/VmUnix/src/Java_mypackage_HelloWorld.c
‘.HelloWorld.class
with the new KVM interpreter. On a Solaris system and from the top of the current release of the CLDC directory hierarchy, we would invoke the KVM interpreter as follows:You should see the following displayed on the standard output:
The high-level process for implementing native methods is illustrated below in FIGURE 2.
KNI Specification K Native Interface (KNI), 1.0 |
Copyright © 2002 Sun Microsystems, Inc. All rights reserved.