JNI传递修改自定义Java Class数组数据

通告:个人博客迁往 https://www.cnblogs.com/xsl-thumb-rfcs
结合前面讲的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对象进行操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将JNI中的char*型转换为Java中的byte数组,可以按照以下步骤进行操作: 1. 获取char*型字符串的长度,使用strlen()函数可以获取。 2. 创建一个jbyteArray型的Java数组,长度为字符串长度,使用NewByteArray()函数可以创建。 3. 将char*型字符串转换为jbyte数组,使用jbyte*型的指针指向char*型字符串,然后使用SetByteArrayRegion()函数将每个char型元素转换为jbyte型并设置到Java数组中。 4. 释放char*型字符串的内存空间,使用free()函数释放。 下面是一个示例代码: ```c++ JNIEXPORT jbyteArray JNICALL Java_com_example_MyClass_charToByteArray(JNIEnv *env, jobject obj, jcharArray charArray) { // 将jcharArray型转换为jchar型指针 jchar *chars = env->GetCharArrayElements(charArray, NULL); // 获取字符串长度 int len = strlen(chars); // 创建jbyteArray型的Java数组 jbyteArray byteArray = env->NewByteArray(len); // 将char*型字符串转换为jbyte型的数组 jbyte *bytes = (jbyte*)chars; env->SetByteArrayRegion(byteArray, 0, len, bytes); // 释放char*型字符串的内存空间 free(chars); // 返回jbyteArray型的Java数组 return byteArray; } ``` 在上面的示例代码中,我们首先将输入的jcharArray型转换为jchar型指针,然后获取字符串长度。接着,我们使用NewByteArray()函数创建一个长度为字符串长度的jbyteArray型的Java数组。然后,我们将jchar型指针转换为jbyte型指针,并使用SetByteArrayRegion()函数将每个char型元素转换为jbyte型并设置到Java数组中。最后,我们使用free()函数释放char*型字符串的内存空间,并返回jbyteArray型的Java数组
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值