public class MyNative
{
public void showParms( String s, int i, boolean b )
{
showParms0( s, i , b );
}
public int hypotenuse( int a, int b )
{
return hyptenuse0( a, b );
}
private native void showParms0( String s, int i, boolean b );
private native int hypotenuse0( int a, int b );
public static int hypotenuse( int a, int b )
{
return hypotenuse0(a,b);
}
...
private static native int hypotenuse0( int a, int b );
现在运行 javah 为 hypotenuse0 创建一个新原型,生成的原型如下所示:
public static void setArray( boolean[] ba )
{
for( int i=0; i < ba.length; i++ )
ba[i] = true;
setArray0( ba );
}
...
private static native void setArray0( boolean[] ba );
在本例中,布尔型数组被初始化为 true,本地方法将把特定的元素设置为 false。同时,在 Java 源代码中,我们可以更改 main 以使其包含测试代码:
boolean[] ba = new boolean[5];
MyNative.setArray( ba );
for( int i=0; i < ba.length; i++ )
System.out.println( ba[i] );
在编译源代码并执行 javah 以后,MyNative.h 头文件包含以下的原型:
The Java Native Interface defines a standard naming and calling convention so that the Java Virtual Machine (VM) can locate and invoke your native methods. This section shows you how to follow the JNI naming and calling conventions so that you can use JNI functions from a native method. It also teaches you how to declare types so that they can be correctly recognized by both the Java program and the native method.
Declaring Native Methods
On the Java side, you declare a native method with the native keyword and an empty method body. On the native side, you provide an implementation for the native method. You must be careful when writing native methods to "match" the native function implementation with the method signature in the Java header file. The javah tool, which is explained in Step 3: Create the .h file, helps you to generate native function prototypes that match the Java-side native method declaration.
Mapping between Java and Native Types
The JNI defines a mapping of Java types and native language (C/C++) types. This section introduces the native types corresponding to both primitive Java types, such as int and double, and Java objects, including strings and arrays.
public native String ProduceExcuteList(String s);
public native String Go(String s);
//public native String DelExcuteList();
static
{
System.loadLibrary("parserLib");
}
}
下面是一个教程,你看看,网上多得是。
Trail: Java Native Interface
Lesson: Interacting with Java from the Native Side
JNI Programming in C++
The JNI provides a slightly cleaner interface for C++ programmers. The jni.h file contains a set of inline C++ functions. This allows the native method programmer to simply write:
The extra level of indirection on env and the env argument to FindClass is hidden from the programmer. The C++ compiler simply expands out the C++ member function calls to their C counterparts; therefore, the resulting code is exactly the same.
The jni.h file also defines a set of dummy C++ classes to enforce the subtyping relationships among different variations of jobject types:
class _jobject {};
class _jclass : public _jobject {};
class _jthrowable : public _jobject {};
class _jstring : public _jobject {};
... /* more on jarray */
typedef _jobject *jobject;
typedef _jclass *jclass;
typedef _jthrowable *jthrowable;
typedef _jstring *jstring;
... /* more on jarray */
The C++ compiler is therefore better able than the C compiler to detect when incorrect types are passed to methods. For example, it is incorrect to pass a jobject to GetMethodID because GetMethodID expects a jclass. You can see this by examining the GetMethodID signature:
The C compiler treats jclass as the same as jobject because it makes this determination using the following typedef statement:
typedef jobject jclass;
Therefore a C compiler is not able to detect that you have mistakenly passed the method a jobject instead of jclass.
The added type safety in C++ comes with a small inconvenience. Recall from Accessing Java Arrays that in C you can fetch a Java string from an array of strings and directly assign the result to a jstring, as follows: