『阿男的技术分享』*Java Native Interface(上)*
我们知道Java本身的实现,很大一部分是用C++写的。实际上,Java也允许我们和原生平台的代码进行交互。
Java定义了一个接口规范,就叫做Java Native Interface
,通过这个接口规范,我们就可以让Java代码运行原生平台的代码。
首先写一个Java的Class^1:
public class HelloJNI {
static {
System.loadLibrary("hello"); // Load native library at runtime
// hello.dll (Windows) or libhello.so (Unixes)
}
// Declare a native method sayHello() that receives nothing and returns void
private native void sayHello();
// Test Driver
public static void main(String[] args) {
new HelloJNI().sayHello(); // invoke the native method
}
}
从上面的代码,我们看到一些平常写Java代码的时候不常看见的东西,首先是这个:
System.loadLibrary("hello");
这个System.loadLibrary
方法可以用来调用平台的原生库。然后是这个:
private native void sayHello();
这个native
关键字意味着这个代码的实现是原生平台实现,而不是Java代码。因此我们要做一个hello
库,提供这个sayHello
方法。
接下来我们用javah
命令生成.h
文件:
$ ls HelloJNI.java
HelloJNI.java
$ javah HelloJNI
$ ls *.h
HelloJNI.h
我们得到了HelloJNI.h
文件,它的内容是根据HelloJNI.java
生成的,我们看看里面的内容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */
#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloJNI
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloJNI_sayHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
可以看到上面的文件里自动生成了JNI
接口规范的一些约定代码。比如jni.h
这个是由JDK提供的,我们稍后要引用。还有sayHello
对应的C/C++
的方法是Java_HelloJNI_sayHello
,这个命名方式可以看出来是Java_ClassName_MethodName
,这个也是JNI
的约定。