JNI返回复杂对象之中的一个

需求:

首先说需求。近期接手一个项目。要在底层解析二进制数据,数据结构比較负责,因为server是c++server,加之開始没有考虑到移动端开发,所以协议有点扯蛋。大体是这种,一个数据包里面是map里面放vector然后序列化成二进制!

ios的还好弄一点。object-c本身支持c++。简单封装就能够了。android的有点麻烦,须要把数据转成java的数据格式,问题来了。c++的数据接口大体是这种:

std::map<std::string,std::vector<struct info> > tmep;

问题:

要转换成java的数据对象。上网搜了一下,没有这方面的资料,有的基本都是一些简单的对象返回,没有这么复杂的,没法。自己动手做了,我的做法是这种:

在java里面声明一个对象类,例如以下:

public class ControlDictionaryValue {
	public String value;
}
public class LoginMsg extends BaseMsg {

	// 字典列表
	public HashMap<String, ArrayList<ControlDictionaryValue> > controlDictionary;
}

通过jni来返回这个对象,jni的代码例如以下:

JNIEXPORT jobject JNICALL Java_com_example_filltriangle_GL2JNILib_test(JNIEnv* env, jclass tis)
    {
        jclass m_login_msg = env->FindClass("hzcw/msgdata/LoginMsg");
        jmethodID m_method_login_msg_init = env->GetMethodID(m_login_msg,"<init>","()V");
        jobject m_login_msg_obj = env->NewObject(m_login_msg, m_method_login_msg_init);
        jfieldID  m_fid_controlDictionary = env->GetFieldID(m_login_msg,"controlDictionary","Ljava/util/HashMap;");

        // new一个hashmap对象
        jclass class_hashmap=env->FindClass("java/util/HashMap");
        jmethodID hashmap_construct_method=env->GetMethodID(class_hashmap, "<init>","()V");
        jobject obj_hashmap =env->NewObject(class_hashmap, hashmap_construct_method, "");
        jmethodID hashmap_put_method= env->GetMethodID(class_hashmap,"put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");

        // new一个ArrayList对象
        jclass class_arraylist=env->FindClass("java/util/ArrayList");
        jmethodID arraylist_construct_method=env->GetMethodID(class_arraylist, "<init>","()V");
        jobject obj_arraylist =env->NewObject(class_arraylist, arraylist_construct_method, "");
        jmethodID arraylist_add_method= env->GetMethodID(class_arraylist,"add","(Ljava/lang/Object;)Z");

        // new一个ControlDictionaryValue对象
        jclass m_cls_ControlDictionaryValue = env->FindClass("hzcw/datastruct/ControlDictionaryValue");
        jmethodID m_mid_ControlDictionaryValue = env->GetMethodID(m_cls_ControlDictionaryValue,"<init>","()V");
        jobject m_obj_ControlDictionaryValue = env->NewObject(m_cls_ControlDictionaryValue, m_mid_ControlDictionaryValue, "");
        // 获取ControlDictionaryValue对象的value变量
        jfieldID  m_fid_ControlDictionaryValue_value = env->GetFieldID(m_cls_ControlDictionaryValue,"value","Ljava/lang/String;");
        env->SetObjectField(m_obj_ControlDictionaryValue,m_fid_ControlDictionaryValue_value,env->NewStringUTF("牙科"));

        env->CallBooleanMethod(obj_arraylist, arraylist_add_method, m_obj_ControlDictionaryValue);

        env->CallObjectMethod(obj_hashmap,hashmap_put_method,env->NewStringUTF((char*)"科室"), obj_arraylist);

        env->SetObjectField(m_login_msg_obj,m_fid_controlDictionary,obj_hashmap);

        env->DeleteLocalRef(m_obj_ControlDictionaryValue);  //删除局部引用
        env->DeleteLocalRef(obj_arraylist);  //删除局部引用
        env->DeleteLocalRef(obj_hashmap);  //删除局部引用

        return m_login_msg_obj;
    }

以上这个是做的假数据,真实的数据自己去填充,做开发的一眼就懂的。

时间: 2024-11-24 17:37:34

JNI返回复杂对象之中的一个的相关文章

JNI返回复杂对象之一

需求: 首先说需求,最近接手一个项目,要在底层解析二进制数据,数据结构比较负责,由于服务器是c++服务器,加之开始没有考虑到移动端开发,所以协议有点扯蛋!大体是这样的,一个数据包里面是map里面放vector然后序列化成二进制!ios的还好弄一点,object-c本身支持c++,简单封装就可以了,android的有点麻烦,需要把数据转成java的数据格式,问题来了,c++的数据接口大体是这样的: std::map<std::string,std::vector<struct info>

一个函数返回临时对象引起的编译器优化问题

我们都知道,如果在一个函数调用另一个函数,假设是 main 函数调用 fun 函数,这个 fun 函数返回一个临时类类型变量,那么这个时候编译器就会在 main 函数申请一个空间并生成一个临时对象,通过拷贝构造函数将 fun 返回的临时变量的值拷贝到这个临时对象.我们看如下的代码: #include <iostream> #include <cstring> using namespace std; class Matrix { public: explicit Matrix(do

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象. 语法EDIT Object.defineProperty(obj, prop, descriptor) 参数 obj 需要定义属性的对象. prop 需定义或修改的属性的名字. descriptor 将被定义或修改的属性的描述符. 返回值 返回传入函数的对象,即第一个参数obj 描述EDIT 该方法允许精确添加或修改对象的属性.一般情况下,我们为对象添加属性是通过

Android NDK开发之Jni调用Java对象

https://my.oschina.net/zhiweiofli/blog/114064 通过使用合适的JNI函数,你可以创建Java对象,get.set 静态(static)和 实例(instance)的域,调用静态(static)和实例(instance)函数.JNI通过ID识别域和方法,一个域或方法的ID是任何处理域和方法的函数的必须参数.下表列出了用以得到静态(static)和实例(instance)的域与方法的JNI函数.每个函数接受(作为参数)域或方法的类,它们的名称,符号和它们对

JNI函数复杂对象传递

主要操作内容,包括如下几个部分: 1.在Native层返回一个字符串 2.从Native层返回一个int型二维数组(int a[ ][ ]) 3.从Native层操作Java层的类: 读取/设置类属性 4.在Native层操作Java层的类:读取/设置类属性.回调Java方法 5.从Native层返回一个复杂对象(即一个类咯) 6.在Java层传递复杂对象至Native层 7.从Native层返回Arraylist集合对象 广而告知,这些操作就是简单的利用一些JNI函数即实现了.so easy

在存放源程序的文件夹中建立一个子文件夹 myPackage。例如,在“D:\java”文件夹之中创建一个与包同名的子文件夹 myPackage(D:\java\myPackage)。在 myPackage 包中创建一个YMD类,该类具有计算今年的年份、可以输出一个带有年月日的字符串的功能。设计程序SY31.java,给定某人姓名和出生日期,计算该人年龄,并输出该人姓名、年龄、出生日期。程序使用YM

题目补充: 在存放源程序的文件夹中建立一个子文件夹 myPackage.例如,在"D:\java"文件夹之中创建一个与包同名的子文件夹 myPackage(D:\java\myPackage).在 myPackage 包中创建一个YMD类,该类具有计算今年的年份.可以输出一个带有年月日的字符串的功能.设计程序SY31.java,给定某人姓名和出生日期,计算该人年龄,并输出该人姓名.年龄.出生日期.程序使用YMD的方法来计算年龄. 主要考包的运用 用到java.util.Calendar

奇妙的动态代理:EF中返回的对象为什么序列化失败

今天有如鹏的学生遇到一个问题:把一个对象保存到Session中(进程外Session)后,Web服务器重启,当从Session读取这个对象的时候报错,提示是一个“T_Users”后面跟着一大串数字的类型,不是“T_Users”类型. 凭着感觉,我问“这个对象是普通对象还是什么对象”,回复说“是Entity Framework返回的对象”,瞬间我知道了:是延迟加载造成的.下面写个程序验证一下. 数据库里建立两张表:一张T_Persons表,一张T_Dogs表,T_Dogs表中有一个MasterId

Math对象产生随机数一个小应用

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>demo-color</title> <link rel="stylesheet" href="http://apps.bdimg.com/libs/bootstrap/3.3.0/css/bootstrap.min.css"> <scri

实战Java虚拟机之中的一个“堆溢出处理”

从今天開始.我会发5个关于java虚拟机的小系列: 实战Java虚拟机之中的一个"堆溢出处理" 实战Java虚拟机之二"虚拟机的工作模式" 实战Java虚拟机之三"G1的新生代GC" 实战Java虚拟机之四"禁用System.gc()" 实战Java虚拟机之五"开启JIT编译" 以下说说[实战Java虚拟机之中的一个"堆溢出处理"] 在Java程序的执行过程中,假设堆空间不足.则有可能抛