Introduction to Using the Raw Native Interface
 
 

Java & Native Code    PreviousRNINext
Introduction to Using the Raw Native Interface     Previous RNI Next

 


A Simple Example

Export the RNIGetCompatibleVersion method from your DLL. All RNI DLLs must export this method; otherwise, an UnsatisfiedLinkError exception is thrown when the method is called. This is a new requirement for the Microsoft VM for Java. Previous releases did not require this export. The following example shows how to export this method.


        #include "native.h";  // RNI declarations (part of Microsoft SDK for
                              // Java)

        __declspec(dllexport)
        DWORD __cdecl RNIGetCompatibleVersion()
        {
            return RNIVER;
        }

Another example is a simple Java class that performs a prime-number sieve. You perform the calculation in C implemented in a DLL called SieveDemo.dll. In Java, the class might look like the following:

    class Sieve
    {
        native static int CountPrimes(byte[] abFlags);

       
        static
        {
            System.loadLibrary("SieveDemo");
        }
    }

Here, CountPrimes is declared native and the loadLibrary call is added in a static block to make sure the DLL that implements the API will be loaded.

Use the Java Language Compiler from Microsoft (jvc) to compile this Java source into a class file with the following:

    jvc Sieve.java

    Microsoft (R) Visual J++ Compiler Version 1.00.XXXX
    Copyright (C) Microsoft Corp 1996. All rights reserved.

Next, use msjavah to produce a header file used by the native code:

    msjavah Sieve

Which will look like the following:

	/* DO NOT EDIT THIS FILE - it is machine generated */
	#include <native.h>
	/* Header for class Sieve */
	
	#ifndef _Included_Sieve
	#define _Included_Sieve
	
	typedef struct ClassSieve {
	#pragma pack(push,1)
	    int32_t MSReserved;
	    char PAD;	/* ANSI C requires structures to have a least one member */
	#pragma pack(pop)
	} ClassSieve;
	#define HSieve ClassSieve
	
	#ifdef __cplusplus
	extern "C" {
	#endif
	__declspec(dllexport) long __cdecl Sieve_CountPrimes(struct HSieve *,HArrayOfByte *);
	#ifdef __cplusplus
	}
	#endif
	#endif

This header file defines a structure ClassSieve that represents the data members of Sieve and a declaration for the native API that is implemented. Since Sieve doesn't have any data members, ClassSieve only contains some housekeeping fields. Native APIs are of the form Package_Class_Member(...) and, since Sieve is not in an explicitly named package, the API that is implemented is Sieve_CountPrimes(). The first parameter to the API is the this pointer, which, for static functions, will always be NULL. The second parameter is the byte array that is manipulated.

Note One useful feature of msjavah is that primitive types (int, boolean, long, and so on) marked static and final become #defines in the resulting header file, making it much easier to share constants.

Next, we implement the C we need:

    #include <varargs.h>
    #include <native.h>
    #include "Sieve.h"

    long cdecl Sieve_CountPrimes(struct HSieve *phThis, HArrayOfByte *phFlags)
    {
        unsigned long count = 0;
        unsigned long i;

        for (i = 0; i < obj_length(phFlags); i++)
            (phFlags->body)[i] = 1;

        for (i = 2; i < obj_length(phFlags); i++)
        {
            if ((phFlags->body)[i] != 0)
            {
                unsigned long k;
                for (k = i + i; k < obj_length(phFlags); k += i)
                    (phFlags->body)[k] = 0;

                count++;
            }
        }

        return count;
    }

This is a fairly standard implementation of a sieve with several helpers from native.h to access to the data of the array (phFlags->body) and to query its length (obj_length(phFlags)).

Next, a .def file to export this API is added:

    LIBRARY         SieveDemo
    DESCRIPTION     'Native DLL for SieveDemo'

    EXPORTS
    	Sieve_CountPrimes
    	RNIGetCompatibleVersion 

Finally, build everything, and then copy the resulting DLL to the system directory and test it.

Top © 1998 Microsoft Corporation. All rights reserved. Terms of use.