1. 程式人生 > >java jni 呼叫c語言函式

java jni 呼叫c語言函式

今日在原始碼中遇到了native關鍵詞,甚是陌生,就查了點資料,對native是什麼東西有了那麼一點了解,並做一小記。

native關鍵字說明其修飾的方法是一個原生態方法,方法對應的實現不是在當前檔案,而是在用其他語言(如C和C++)實現的檔案中。Java語言本身不能對作業系統底層進行訪問和操作,但是可以通過JNI介面呼叫其他語言來實現對底層的訪問。

JNI是Java本機介面(Java Native Interface),是一個本機程式設計介面,它是Java軟體開發工具箱(Java Software Development Kit,SDK)的一部分。JNI允許Java程式碼使用以其他語言編寫的程式碼和程式碼庫。Invocation API(JNI的一部分)可以用來將Java虛擬機器(JVM)嵌入到本機應用程式中,從而允許程式設計師從本機程式碼內部呼叫Java程式碼。

不過,對Java外部的呼叫通常不能移植到其他平臺,在applet中還可能引發安全異常。實現原生代碼將使您的Java應用程式無法通過100%純Java測試。但是,如果必須執行本地呼叫,則要考慮幾個準則:

1.將您的所有本地方法都封裝到一個類中,這個類呼叫單個的DLL。對每一種目標作業系統平臺,都可以用特定於適當平臺的版本的DLL。這樣可以將原生代碼的影響減少到最小,並有助於將以後所需要的移植問題考慮在內。

2.本地方法儘量簡單。儘量使您的本地方法對第三方(包括Microsoft)執行時DLL的依賴減少到最小。使您的本地方法儘量獨立,以將載入您的DLL和應用程式所需的開銷減少到最小。如果需要執行時DLL,必須隨應用程式一起提供。

JNI的書寫步驟如下:

a.編寫帶有native宣告的方法的Java類

b.使用javac命令編譯編寫的Java類

c.使用java -jni ****來生成字尾名為.h的標頭檔案

d.使用其他語言(C、C++)實現本地方法

e.將本地方法編寫的檔案生成動態連結庫

以下是一個在Java中呼叫本地C程式的簡單的例子:

a.編寫HelloWorld.java類

class HelloWorld{

public native void hello();

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

public static void main(String[] args){

new HelloWorld().hello();
}

}

b.編譯

javac HelloWorld.java

c.生成.h檔案

javah -jni HelloWorld

生成內容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_hello
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

第一個引數是呼叫JNI方法時使用的JNI Environment指標。第二個引數是指向在此Java程式碼中例項化的Java物件HelloWorld的一個控制代碼。其他引數是方法本身的引數

d.c實現

#include <jni.h>
#include "HelloWorld.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloWorld_hello(JNIEnv *env,jobject obj){
printf("Hello World!\n");
return;
}

其中,第一行是將jni.h檔案引入(在%JAVA_HOME%\include目錄下),裡邊有JNIEnv和jobject的定義。

e.編譯c實現

這裡以在Windows中為例,需要生成dll檔案。在儲存HelloWorldImpl.c資料夾下面,使用VC的編譯器cl成。

cl -I%java_home%\include -I%java_home%\include\win32 -LD HelloWorldImp.c -Fehello.dll

注意:生成的dll檔名在選項-Fe後面配置,這裡是hello,因為在HelloWorld.java檔案中我們loadLibary的時候使用的名字是hello。當然這裡修改之後那裡也需要修改。另外需要將-I%java_home%\include -I%java_home%\include\win32引數加上,因為在第四步裡面編寫本地方法的時候引入了jni.h檔案。

6) 執行程式

java HelloWorld就ok了!

例子是照著別人的網頁做的,其他還有很多東西,可以看資源連線。

資源:

J2SE5的Java Native Interface Specification