声明:迁移自本人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数组数据的更多相关文章

  1. Android中关于JNI 的学习(三)在JNI层訪问Java端对象

    前面两篇文章简介了JNI层跟Java层的一些相应关系,包含方法名,数据类型和方法名称等,相信在理论层面.可以非常好地帮助我们去了解JNI在Native本地开发中的作用,对JNI的一些概念也有了一个初步 ...

  2. 实现JNI的另一种方法:使用RegisterNatives方法传递和使用Java自定义类 (转)

    原帖地址:http://blog.csdn.net/qiuxiaolong007/article/details/7860610 除了使用传统方法实现JNI外,也可以使用RegisterNatives ...

  3. Java中使用自定义类封装数组,添加类方法实现数据操作

    1.具体见注释 2.后续或有更新 public class MyArray { private long[] array; private int cnt; // 自定义数组类的元素个数 /** 使用 ...

  4. JNI中修改(基本类型)参数并返回到Java层使用

    最近在JNI相关项目中遇到一个问题:在Java层传入多个int类型的参数,在jni层修改参数值或地址之后重新返回到Java层.这应该算是基本知识了,尤其是基本类型的参数往往看似简单,所以在之前学习jn ...

  5. Java 从数组来看值传递和引用传递

    从数组来看值传递和引用传递 惯例先看一段代码 public class DemoCollection14 { public static void main(String[] args) { Stri ...

  6. 从文件中读取数组数据————Java

    自己总结一下Java文件的读取类似数组数据的方法,自己可以快速查看. 一.规整化数据: 对于数组数据是一一对应的情况 ArrayList<String> arrayList = new A ...

  7. JNI C创建Java字符串数组

    创建Java字符串数组 注:jni中没有与String[]对应的数据类型,所以需要创建对象数组,循环添加jstring对象 #include <Sample3.h> #include &l ...

  8. 转:Java修改Excel单元格的数据及格式

    https://blog.csdn.net/aking21alinjuju/article/details/6001153?locationNum=2 继前两节的Java读取.写入Excel后,本期将 ...

  9. [z]protobuf实现c++与java之间的数据传递,beancopy数据到前台

    [z]http://blog.csdn.net/xhyzdai/article/details/46684335 定义proto文件 option java_package = "com.w ...

随机推荐

  1. 删除C代码中的注释行【状态机】

    今天在学ruby时遇到的一个经典的题目,一直都知道但从来没有实现过.呈上状态机,代码略.(写代码的时候还是需要注意一些小情况的)

  2. CharacterEncodingFilter详解及源码解析

    字符编码过滤器  (Spring框架对字符编码的处理) 基于函数回调,对所有请求起作用,只在容器初始化时调用一次,依赖于servlet容器. web.xml配置文件 <filter> &l ...

  3. leetcode1019 Next Greater Node In Linked List

    """ We are given a linked list with head as the first node. Let's number the nodes in ...

  4. ERP开发准备

    Delphi 开发 ERP [1] 准备 使用的控件FireDac.DevExpress.FastReport. FireDac:新一代的数据库控件. DevExpress:界面UI. FastRep ...

  5. URL短网址系统的算法设计及实践

    在通常情况下,URL是由系统生成的,通常包括URI路径,多个查询参数,可以对参数进行加密和解密.当人们要分享某个URL,比如短信,邮件,社交媒体,这就需要短URL. 而短网址,顾名思义就是在长度上比较 ...

  6. Day 31:CSS选择器、常用CSS样式、盒子模型

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. 小程序封装API

    一般我们https请求都是通过wx.request来请求,但是这种请求如果多了,页面会混乱不说,还不好管理,因此我将请求单独拎出去,方便管理,也方便后期维护. // api.js const API_ ...

  8. CentOS 6.x 重置root 密码

    1.重启,进入启动界面,快速按e,进入GNU GRUB界面. 2.选择第二项,按e,进行编辑. 3.在末尾输入1或single,回车,返回上一界面,还是选第二项,按b,进入单用户模式. 此时输入命令  ...

  9. 设置gvim的字体大小

    1.临时设置: 进入命令行模式输入: set guifont=Courier\ New:h10 2.永久设置: 打开安装目录找到defaults.vim在最后一行输入: set guifont=Cou ...

  10. ServletContext 详解

    ServletContext——它是一个全局的储存信息的空间,服务器开始,其就存在,服务器关闭,其才释放.request,一个用户可有多个:session,一个用户一个:而servletContext ...