Java 端代碼
JniFuncMain.java
public class JniFuncMain{
private static int staticIntField = 300;
//加載本地庫 jnifunc
static { System.loadLibrary("jnifunc");}
//本地方法聲明
public static native JniTest createJniObject();
public static void main(String[] args){
//從本地代碼生成 JniTest 對象
System.out.println("[Java] createJniObejct() 調用本地方法");
JniTest jniObj = createJniObject();
//調用 JniTest 對象的方法
jniObj.callTest();
}
}
JniTest.java
class JniTest{
private int intField;
//構造方法
public JniTest(int num){
intField = num;
System.out.println("[java] 調用JniTest對象的構造方法:intField = " + intField);
}
//此方法由JNI本地函數調用
public int callByNative(int num){
System.out.println("[Java] JniTest對象的callByNative("+ num +")調用");
return num;
}
public void callTest(){
System.out.println("[Java] JniTest對象的callTest()方法調用:intField="+intField);
}
}
生成C++頭文件
編譯 JniFuncMain.java
javac JniFuncMain.java
生成頭文件
javah JniFuncMain
JniFuncMain.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JniFuncMain */
#ifndef _Included_JniFuncMain
#define _Included_JniFuncMain
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JniFuncMain
* Method: createJniObject
* Signature: ()LJniTest;
*/
JNIEXPORT jobject JNICALL Java_JniFuncMain_createJniObject
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
實現頭文件中聲明的函數
jnifunc.cpp
#include "JniFuncMain.h"
#include "stdio.h"
JNIEXPORT jobject JNICALL Java_JniFuncMain_createJniObject(JNIEnv *env, jclass clazz){
jclass targetClass;
jmethodID mid;
jobject newObject;
jstring helloStr;
jfieldID fid;
jint staticIntField;
jint result;
//獲取 JniFuncMain 類的 staticIntField 變量值
fid = env->GetStaticFieldID(clazz, "staticIntField", "I");
staticIntField = env->GetStaticIntField(clazz, fid);
printf("[CPP] 獲取 JniFuncMain 類的 staticIntField 值\n");
printf("JnifuncMain.staticlntField = %d\n", staticIntField);
//查找生成對象的類
targetClass = env->FindClass("JniTest");
//查找構造方法
mid = env->GetMethodID(targetClass, "<init>", "(I)V");
//生成 JniTest 對象(返回對象的引用)
printf("[CPP] JniTest 對象生成\n");
newObject = env->NewObject(targetClass, mid, 100);
//調用對象的方法
mid = env->GetMethodID(targetClass, "callByNative", "(I)I");
result = env->CallIntMethod(newObject, mid, 200);
//設置JniTest 對象的 intField 值
fid = env->GetFieldID(targetClass, "intField", "I");
printf("[CPP] 設置 JniTest 對象的 intField 值爲200\n");
env->SetIntField(newObject, fid, result);
//返回對象的引用
return newObject;
}
編譯生成本地共享庫
gcc -shared -fPIC -I /usr/lib/jvm/java-7-openjdk-amd64/include jnifunc.cpp -o libjnifunc.so
運行
java -Djava.library.path=. JniFuncMain
結果:
參考資料:
《Android框架揭祕》