做android开发的时候,我们经常需要在java C++之间传递数据,android里面自带的处理 如果是结构体的话一般是在java定义一个对象,在c++层对应一个结构体可类进行赋值
如在sensor里面
sensors_module_get_next_sensor(Sensor sensor, int next);
java定义的是一个Sensor对象
而在其native函数中对应给譔对象赋值是通过下面的语句进行的
env->SetObjectField(sensor, sensorOffsets.name, name);
env->SetObjectField(sensor, sensorOffsets.vendor, vendor);
env->SetIntField(sensor, sensorOffsets.version, 1);
假如我们C++层有很多的结构体,而我们在jni调用中需要把这些结构体的值都传到Java上去,那么我们需要在Java层都定义相应的Java对象,而且设置起值来也比较麻烦,所以这种方法不太好,太麻烦。
第二种方法是在Java通过jni调用分配一块内存,并返回这块内存的地址,后面需要传参的时候在C++层通过指针赋值,这个存在大小端问题比较麻烦,而且在要调频繁调用Jni函数,后面会有一个做好的实例。
第三处方法就是通过XML,把要传的参数通过XML组织好,以字符串的形式在JAva C++进行传递,这个方式解析起来有点麻烦,最后一个方式,是通过Android里面的json方式。
这里重点介绍下
参数组织形式:
"{\"name\": \"xiaoming\",\"age\": 22}";
这时传递了两个参数,一个是name,它的值是xiaoming,另一个是age,它的值。也就是说,假如java需要向C++传递这两上值,只要写成上面这种形式
再看一个复杂点的
struct person
{
char name[25];
int age;
}
假设要传的参数值为:
name:xiaoli
age:26
struct person pStr[2];
pStr[0].name = xiaoming
pStr[0].age = 22
pStr[0].name = xiaoma
pStr[0].age = 21
对应传递的字符串参数:
p += sprintf(p, "{");
p += sprintf(p, " \"name\":\"%s\" ,","xiaoli");
p += sprintf(p, " \"age\":%d,",26);
p += sprintf(p, " \"pStr\":");
p += sprintf(p, "[");
p += sprintf(p, "{");
p += sprintf(p, " \"name\":\"%s\",","xiaoming");
p += sprintf(p, " \"age\":%d",22);
p += sprintf(p, "},");
p += sprintf(p, "{");
p += sprintf(p, " \"name\":\"%s\",","xiaoma");
p += sprintf(p, " \"age\":%d",21);
p += sprintf(p, "}");
p += sprintf(p, "]");
P += sprintf(p, "}");
对于数组:
Array[2]
p += sprintf(p, "{");
p += sprintf(p, " \"array\":");
p += sprintf(p, "[");
p += sprintf(p, "%d,",26);
p += sprintf(p, "%d",27);
p += sprintf(p, "]");
p += sprintf(p, "}");
通过阅读json代码,了解了json里面是怎么组织这些数据的
这个就是前面 struct person pStr[2]中各个成员在json中的组织。
我们把数据让json解析后,对于像p.a[0].b[0]的查找过程:
先找到a的json_t指针,再找到b的json_t指针,一直这样往下找
观察上面的图可以看出JSON_OBJECT的next为JSON_OBJECT
JSON_STRING的next为JSON_STRING等,这样像数组这种获取到下标后直接next相应的次数即可以很快找到其数据
使用:
json_t*root = NULL, *q = NULL;
if (mjson_parse(&root, (char*) json) != 0) {
LOGE("json parse failed!\n");
ret = -1;
goto BAIL;
}
if (mjson_try_begin() < 0) {
LOGE("invalid !!!\n");
ret = -1;
goto BAIL;
}
q = root;
name = mjson_locate_string(q, "name");
age = mjson_locate_number(q, "age");
mjson_try_end();
BAIL: if (root)
mjson_free(root);
json C 代码:
http://download.csdn.net/detail/new_abc/4352926
参考:
http://blog.csdn.net/xiedantibu/article/details/7004905
http://www.cnblogs.com/mattmonkey/archive/2011/08/24/2301551.html
http://yuanzhifei89.iteye.com/blog/1141385
http://www.linuxso.com/linuxbiancheng/12502.html