JNI是Java Native Interface的英文縮寫, 中文翻譯爲本地調用, 自從Java 1.1開始就成爲了Java標準的一部分.html
C/C++是系統級的編程語言, 能夠用來開發任何和系統相關的程序和類庫, 可是Java自己編寫底層的應用比較難實現, 使用JNI能夠調用現有的本地庫, 極大地靈活了Java的開發.java
C/C++的效率是目前最好的語言, 能夠使用C/C++來實現一些實時性很是高的部分. C/C++和Java自己都是很是流行的編程語言, 一些大型軟件中常用語言之間的混合編程.linux
鑑於目前網絡上JNI的文章不是特別多, 我將本身的一些總結寫在這裏. 若有錯漏, 歡迎指正!編程
Java調用C/C++大概有這樣幾個步驟windows
編寫帶有native方法的Java類, 使用javac工具編譯Java類bash
使用javah來生成與native方法對應的頭文件網絡
實現相應的頭文件, 並編譯爲動態連接庫(windows下是.dll, linux下是.so)編程語言
下面就完整的介紹一個簡單的Java調用C/C++的例子, 這個例子是來自http://www.ibm.com/developerworks/cn/education/java/j-jni/index.html, 不過其中有一些錯誤, 這個文章是很是不錯的JNI學習資料, 可是很是古老.工具
咱們來編寫一個Sample1的java類學習
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public
class
Sample1 {
public
native
int
intMethod(
int
n);
public
native
boolean
booleanMethod(
boolean
bool);
public
native
String stringMethod(String text);
public
native
int
intArrayMethod(
int
[] intArray);
public
static
void
main(String[] args) {
System.loadLibrary(
"Sample1"
);
Sample1 sample =
new
Sample1();
int
square = sample.intMethod(
5
);
boolean
bool = sample.booleanMethod(
true
);
String text = sample.stringMethod(
"Java"
);
int
sum = sample.intArrayMethod(
new
int
[]{
1
,
2
,
3
,
4
,
5
,
8
,
13
});
System.out.println(
"intMethod: "
+ square);
System.out.println(
"booleanMethod: "
+ bool);
System.out.println(
"stringMethod: "
+ text);
System.out.println(
"intArrayMethod: "
+ sum);
}
}
|
上面有4個native方法, 分別是4種類型的參數, int, boolean, String, int[].
其中有一句比較重要, 這句話加載了動態類庫
System.loadLibrary("Sample1");
在windows下加載的就是Sample1.dll, 在linux下加載的就是Sample1.so.
本文使用的windowws, 因此後面使用Sample1.dll來表示Sample1動態連接庫.
注意: 不能夠在代碼中寫上後綴dll或so. 還要保證Sample1.dll在path路徑中. 這個Sample1.dll是咱們後面須要編譯出來的東西.
4個native方法就是咱們須要用C來實現的方法.
編譯Sample1.java, 使用命令行(windows是cmd, linux下通常是bash)
>javac Sample1.java
能夠看到Sample1.class文件
在命令行中運行
>javah Sample1
能夠在目錄下看到一個新文件Sample1.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Sample1 */
#ifndef _Included_Sample1
#define _Included_Sample1
#ifdef __cplusplus
extern
"C"
{
#endif
/*
* Class: Sample1
* Method: intMethod
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_Sample1_intMethod
(JNIEnv *, jobject, jint);
/*
* Class: Sample1
* Method: booleanMethod
* Signature: (Z)Z
*/
JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
(JNIEnv *, jobject, jboolean);
/*
* Class: Sample1
* Method: stringMethod
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
(JNIEnv *, jobject, jstring);
/*
* Class: Sample1
* Method: intArrayMethod
* Signature: ([I)I
*/
JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
(JNIEnv *, jobject, jintArray);
#ifdef __cplusplus
}
#endif |