Java 與 C++ 通過 JNI 交互(Java 主程序)

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框架揭祕》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章