Contents Previous Next

Chapter   6

KNI Programming Overview


6.1 The ‘kni.h’ Include File

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

6.2 Sample KNI Application

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.

6.2.1 Java Code

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.

6.2.2 The Corresponding Native Code

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:

    void Java_mypackage_HelloWorld_sayHello() 

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:

6.2.3 Compiling and Running the Sample Application in the KVM


Note – The information provided in this subsection is KVM-specific and not part of the KNI Specification. Implementation details for other Java virtual machines supporting the K Native Interface may be entirely different.

Below is a summary of the steps to run the sample KNI application in the KVM:

  1. Create the Java class source file 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.
  2. Create a C source file 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‘.
  3. Now that the native method has been implemented, we need to rebuild the KVM runtime interpreter and update its native function table (e.g., ${KVM_ROOT}/tools/jcc/nativeFunctionTableUnix.c); this latter step is performed by JavaCodeCompact. Rebuild the KVM system by compiling it with the following compilation option:
  4.     gnumake USE_KNI=true 
    
  5. Run the Java class bytecode file 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:
   ${KVM_ROOT}/kvm/VmUnix/build/kvm -classpath                  ${KVM_ROOT}/api/classes mypackage.HelloWorld 

You should see the following displayed on the standard output:

hello, world! 

The high-level process for implementing native methods is illustrated below in FIGURE 2.

Flow chart showing the four steps to implementing a native method with KNI.[D]

FIGURE 2  –  Steps involved in implementing native methods

 


Contents Previous Next KNI Specification
K Native Interface (KNI), 1.0