JNI传递修改自定义Java Class数组数据
声明:迁移自本人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对象进行操作。
JNI传递修改自定义Java Class数组数据的更多相关文章
- Android中关于JNI 的学习(三)在JNI层訪问Java端对象
		
前面两篇文章简介了JNI层跟Java层的一些相应关系,包含方法名,数据类型和方法名称等,相信在理论层面.可以非常好地帮助我们去了解JNI在Native本地开发中的作用,对JNI的一些概念也有了一个初步 ...
 - 实现JNI的另一种方法:使用RegisterNatives方法传递和使用Java自定义类 (转)
		
原帖地址:http://blog.csdn.net/qiuxiaolong007/article/details/7860610 除了使用传统方法实现JNI外,也可以使用RegisterNatives ...
 - Java中使用自定义类封装数组,添加类方法实现数据操作
		
1.具体见注释 2.后续或有更新 public class MyArray { private long[] array; private int cnt; // 自定义数组类的元素个数 /** 使用 ...
 - JNI中修改(基本类型)参数并返回到Java层使用
		
最近在JNI相关项目中遇到一个问题:在Java层传入多个int类型的参数,在jni层修改参数值或地址之后重新返回到Java层.这应该算是基本知识了,尤其是基本类型的参数往往看似简单,所以在之前学习jn ...
 - Java 从数组来看值传递和引用传递
		
从数组来看值传递和引用传递 惯例先看一段代码 public class DemoCollection14 { public static void main(String[] args) { Stri ...
 - 从文件中读取数组数据————Java
		
自己总结一下Java文件的读取类似数组数据的方法,自己可以快速查看. 一.规整化数据: 对于数组数据是一一对应的情况 ArrayList<String> arrayList = new A ...
 - JNI C创建Java字符串数组
		
创建Java字符串数组 注:jni中没有与String[]对应的数据类型,所以需要创建对象数组,循环添加jstring对象 #include <Sample3.h> #include &l ...
 - 转:Java修改Excel单元格的数据及格式
		
https://blog.csdn.net/aking21alinjuju/article/details/6001153?locationNum=2 继前两节的Java读取.写入Excel后,本期将 ...
 - [z]protobuf实现c++与java之间的数据传递,beancopy数据到前台
		
[z]http://blog.csdn.net/xhyzdai/article/details/46684335 定义proto文件 option java_package = "com.w ...
 
随机推荐
- 5 GC 参数
 - JS 选择电脑中的文件目录
			
按钮调用方法function CarryOut(){ var inputObj=document.createElement('input') inputObj.setAttribute('id',' ...
 - python scipy优化器模块(optimize)
			
pyhton数据处理与分析之scipy优化器及不同函数求根 1.Scipy的优化器模块optimize可以用来求取不同函数在多个约束条件下的最优化问题,也可以用来求取函数在某一点附近的根和对应的函数值 ...
 - windows上通过自定义后缀文件启动Unity应用
			
好吧,一个Unity应用并不常见的需求.. 两个步骤 1.关联注册表 2.把自定义后缀文件作为启动参数传给Unity做处理 1.关联注册表 (.XXXX是自定义后缀) Windows Registr ...
 - POJ  2829  Buy Tickets
			
Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 26443 Accepted: 12639 Des ...
 - OpenMandriva或将放弃32位的支持
			
导读 除了Ubuntu计划在其19.10发行版中删除32位包之外,OpenMandriva开发团队也是另一个备受关注的Linux发行版起草计划,以取消对32位包的支持. OpenMandriva计划在 ...
 - nodejs —— 流追加数据
			
在写入流的文档后添加 ,{ 'flags': 'a' } 即可 : var fs = require('fs') var readerStream ...
 - 使用pip install jupyter报错处理办法及修改Jupyter默认加载路径的方法
			
1.配置python环境之后想使用Jupyter,网上查看可以使用pip install Jupyter安装,执行命令行后正常安装,安装到一半以后报错,如图1.2 图1 图2 2.发现是安装过程中安装 ...
 - 配置gem5-gpu模拟环境
			
// 系统:ubuntu 14.04,显卡:支持CUDA的显卡.建议换aliyun的源!先clean软件源再update.// 在Ubuntu 16.04上试过,配好环境变量,编译出错(把14.04上 ...
 - POJ 1770 树形DP
			
咋一看确实想到的是树形DP,但是我一开始也马上想到环的情况,这样应该是不可以进行树形DP的,然后我自以为是地想用有向图代替无向图,而且总是从能量高的指向能量低的,这样自以为消除了环,但是其实是不对滴, ...