JNI 記錄

摘要:JNI 記錄

Java call C

 

Step 1: Write the Java Code

建立HelloWorld.java


//HelloWorld.java
public class HelloWorld
{
    public native void showHelloWorld();
    static {
        System.loadLibrary("hello");//呼叫libhello.so
    }
                public static void main(String[] args){
                                new HelloWorld().showHelloWorld();
                }
}

 

Step 2: Compile the Java Code
執行javac HelloWorld.java //編譯

Step 3: Create the .h File (這是自動產生出的不要去編輯)
javah -jni HelloWorld //自動產生對應C標頭檔,內容中粗體為C的函式宣告:
-d選項可以指定輸出路徑
-jni 表示產生jni標頭檔案
 

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

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

#ifdef __cplusplus
}
#endif
#endif

Step 4: Write the Native Method Implementation
建立jni.c


//hello.c
#include 
#include "HelloWorld.h"
#include 

JNIEXPORT void JNICALL
Java_HelloWorld_showHelloworld(JNIEnv *env, jobject obj)
{
                printf("Hello world!\n");
                return;
}

 

Step 5: Create a Shared Library
執行
gcc -fPIC -shared -Ijni.h 目錄> -Ijni_md.h目錄> jni.c -o libjni.so

 

 

C call Java

C訪問java不能透過函數指標 只能透過通用的參數介面
需要把想要訪問的類別名 函數名稱 參數傳遞給java引擎
 
訪問Java中函數的流程:
 
1. 取得Java對象的類別
cls = env -> GetObjectClass(jobject)
 
2. 取得Java函數的id值
jmethodId mid = env -> GetMethodId(cls, "method_name", "([Ljava/lang/String;)V");
 
第二個參數為Java中的函數名稱
第三個參數為Java函數的參數和返回值
 
Java提供javap工具 可以查看Java函數的輸入 返回參數
javap -s com/android/HelloWorld
 
-s的含義是簽名(Signature) 因為Java允許函數重載 所以不同的參數 返回值代表著不同的函數
 
3. 找到函數後 就可以使用該函數
env -> CallXXXMethod(jobject, mid, ret);
 
訪問Java中變數的流程:
 
1. cls = env -> GetObjectClass(jobject)
 
取得變數的id值
2. jfieldId fid = env -> GetFiledId(cls, "filed_name", "I");
 
field_name為Java變數的名稱
第三個參數為變數的類型
 
3. 取得變數值
value = env -> GetXXXField(env, jobject, fid)



 

JNIEnv 表示Java環境, jobject 指向呼叫的物件
java: int, long, byte, boolean, char, short, float, double, object
c中表示類型前面加一個j來表示
 
jclass取得:   
jclass FindClass(const char*, clsName);
jclass GetObjectClass(jobject obj);
jclass GetSuperClass(jclass obj);
 
jclass cls_string = env -> FindClass("java/lang/String") 取得string類型方式
 
取得方法名:
GetFieldID/GetMethodID
GetStaticFieldID/GetStaticMethodID
 
Java類型
native類型
boolean
Z
byte
B
char
C
double
D
float
F
int
I
long
L
Object
‘L’+’package’+’;’
short
S
 
object ---> Ljava/lang/Sting;
Array ---> [Ljava/lang/object;