JNI返回复杂对象之一

需求:

首先说需求,最近接手一个项目,要在底层解析二进制数据,数据结构比较负责,由于服务器是c++服务器,加之开始没有考虑到移动端开发,所以协议有点扯蛋!大体是这样的,一个数据包里面是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;
    }

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

JNI返回复杂对象之一,布布扣,bubuko.com

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

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

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

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

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

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

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

Linq结果直接返回实体对象

说到Linq返回结果集,我们一般都会这样做: var result=from s in db.Students join c in db.Classes on s.ClassID equals c.ClassID select new { Id = s.Id, Name = c.Name, Address = c.Address }; 然后我们就直接操作result结果集或者是再进一步转换为实体对象. 现在,我们可以直接让Linq返回实体对象,这样就省去转换的麻烦了.代码如下: IEnumera

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

我们都知道,如果在一个函数调用另一个函数,假设是 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 studio2.3.3 模拟器 Jni函数调用C++对象,lldb调试this指针和相关变量显示无效的原因

android studio2.3.3 的版本中 Jni函数调用C++对象,对象调用相关的成员函数, lldb调试,变量跟踪窗口,this指针和相关变量显示无效的原因,但这些参数实际是有效的,只是debug lldb调试环境出错. 原因是模拟器选择  x86 架构的就会出现问题 模拟器选择arm 架构的 this指针就会正确显示,这个问题的原因还需要继续查找. 所以说尽量用真机调试,不要用模拟器来调试.

判断JSON返回的对象中的firstName这一列的值是否包含指定的字符

判断JSON返回的对象中的firstName这一列的值是否包含指定的字符,如果包含指定字符则返回true,否则返回false 标签: <无> 代码片段(1)[全屏查看所有代码] 1. [代码][其他]代码 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51