声明:迁移自本人CSDN博客https://blog.csdn.net/u013365635

结合前面讲的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对象进行操作。