通过JNI实现Java向C传递复杂数据结构HashMap<String, String[]>

方式一: 传递Java对象

JAVA是可以传递Object的, 可以通过传递Object, 然后通过类似反射的方式读取object的方法然后调用该方法, 读取属性, 获取属性的值, 然后转变成C对应的类型.
参考: Java向C传递HashMap
整个逻辑按部就班就好, 但是代码特别冗杂, 详见参考中的代码逻辑.
优点: 逻辑鲜明, 代码结构清晰
缺点: 冗杂

方式二: 传递JNI能接受的基本类型, C再解析

这需要将一个对象先用JNI能理解的类型编码, 比如编码成String, 成String[], 成int, long等

比如传递HashMap <String, String>, 可以这样
编码

可以将该map编码成一个String数组, 然后将该String数组和String数组的类型传到native层
1 . 将Map转成String数组

    private void setParams(Map<String, String> params) {
        if (params != null && params.size() != 0) {
            mParams = new String[params.size() * 2];
            int i = 0;
            for (String key : params.keySet()) {
                mParams[2 * i] = key;
                mParams[2 * i + 1] = params.get(key);
                i++;
            }
        } else {
            mParams = new String[]{};
        }
    }

2 . 传递给native层

...mParams, mParams.length...
// 传递数组和数组的大小

3 . 解析jobjectArray j_params, 和jint j_len_param放到vector里面, 两个参数是从JAVA传过来的

    std::vector<string> params;
    for (int i = 0; i < j_len_param; i++) {
        jobject obj_param_i = env->GetObjectArrayElement(j_params, i);
        const char *c_param0 = env->GetStringUTFChars((jstring) obj_param_i, 0);
        params.push_back(c_param0);
    }

4 . 根据params的下标是奇数还是偶数判断是key还是value

如何传递HashMap <String, String[]>

这个就比较麻烦, 可以这样编码
仍然用一个String[]去传key, Values[]也取出来取出来后直接一个一个的接着key放置, 比如

String[] paramArray = new String[] {key1, key1Value1, key1Value2, key2, key2Value1, key2Value2, key2Value3...}

同时记录每一个key对应Values的size, size1, size2, size3, 最后将将他们放到一个数组里

// +1加的是key的个数1个
int[] sizes = new int[] {size1 + 1, size2 + 1...}

最后传递给JNI的参数包括

// C无法获取数组的长度所以需要需要传递每个数组的size
paramArray sizes sizes.size()

获取paramArray的长度:
在C层取出sizes对应的数组对象, 对int[]数组累加求和就是paramArray的长度
每一个key value1, value2的大小都是对应sizes中的一个元素

总结

希望本文能对你在传递复杂对象上有所启发

简单来讲就是, 分解->组装成JNI能传递的类型->分解成native基本类型->组装成native层方便使用的类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值