JNI傳遞修改自定義Java Class陣列資料
阿新 • • 發佈:2018-12-14
結合前面講的2篇關於JNI的文章,這裡直接把程式碼貼上,主要是要知道如果傳遞自定義Class Array的時候,在JNI怎麼處理。單獨拎出來講解,是因為和系統自帶型別如long Array、String等的處理還是往往會有所區別的。可以做了寫程式碼時迷惑時的一個參考。
自定義POJO類
package com.testjni; public class AObject { int a; int b; public int getA() { return a; } public void setA(int a) { this.a = a; } public int getB() { return b; } public void setB(int b) { this.b = b; } /** * {@inheritDoc} */ @Override public String toString() { final StringBuilder sb = new StringBuilder("AObject").append('[').append("a=").append(a).append(",b=").append(b).append(']'); return sb.toString(); } }
Java測試類
package com.testjni; public class TestJNI { public native boolean testJobjectArray(AObject[] aObjects); static { System.load("D:\\eclipseWebWorkSpace\\testest\\src\\com\\testjni\\libTestJNI_amd64.dll"); } public static void main(String[] args) { TestJNI testJNI = new TestJNI(); AObject[] aObjects = new AObject[3]; for (int i = 0; i < 3; i++) { aObjects[i] = new AObject(); } for (int i = 0; i < 3; i++) { System.out.println("aObjects[" + i + "]=" + aObjects[i]); } testJNI.testJobjectArray(aObjects); System.out.println("\n\n\nafter modified by jni"); for (int i = 0; i < 10; i++) { System.out.println(i + "-->" + aObjects[i]); } } }
JNI標頭檔案com_testjni_TestJNI.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include "jni.h" /* Header for class com_testjni_TestJNI */ #ifndef _Included_com_testjni_TestJNI #define _Included_com_testjni_TestJNI #ifdef __cplusplus extern "C" { #endif /* * Class: com_testjni_TestJNI * Method: test_jobjectArray * Signature: ([Lcom/testjni/AObject;)Z */ JNIEXPORT jboolean JNICALL Java_com_testjni_TestJNI_testJobjectArray (JNIEnv *, jobject, jobjectArray); #ifdef __cplusplus } #endif #endif
JNI 原始碼檔案com_testjni_TestJNI.cpp
#include <stdio.h>
#include "com_testjni_TestJNI.h"
#include "jni.h"
static const char* const AObjectClassPath = "com/testjni/AObject";
JNIEXPORT jboolean JNICALL Java_com_testjni_TestJNI_testJobjectArray(JNIEnv *env, jobject obj, jobjectArray aObjects)
{
jint arrLen = env->GetArrayLength(aObjects);
printf("\narrLen=%d", nArrLen);
jclass aObjectClass = env->FindClass(AObjectClassPath);
if (aObjectClass == NULL)
{
return true;
}
jfieldID afield = env->GetFieldID(aObjectClass, "a", "I");
jfieldID bfield = env->GetFieldID(aObjectClass, "b", "I");
for (int i = 0; i < 3; i++)
{
jobject aObject = env->GetObjectArrayElement(aObjects, i);
env->SetIntField(aObject, afield, i*i);
env->SetIntField(aObject, bfield, i*(i+1));
}
}
編譯命令 cl /LD D:\eclipseWebWorkSpace\testest\src\com\testjni\com_testjni_TestJNI.cpp -o D:\eclipseWebWorkSpace\testest\src\com\testjni\libTestJNI_amd64.dll 執行結果: before modified by jni aObjects[0]=AObject[a=0,b=0] aObjects[1]=AObject[a=0,b=0] aObjects[2]=AObject[a=0,b=0]
after modified by jni aObjects[0]=AObject[a=0,b=0] aObjects[1]=AObject[a=1,b=2] aObjects[2]=AObject[a=4,b=6]
arrLen=3 關鍵的方法就是GetObjectArrayElement,取出jobjectArray中的元素,然後對這些自定義Class物件進行操作。