如何在jni中访问传递给c的JSON数据?

如何在jni中访问传递给c的JSON数据?,c,json,java-native-interface,C,Json,Java Native Interface,我的java程序将JSONObject传递给本机程序,如下所示: import org.json.simple.JSONObject; class json{ static{ System.loadLibrary("json"); } private native void json(JSONObject j); public static void main(String args[]){ json js = new json(); JSONObject j =

我的java程序将JSONObject传递给本机程序,如下所示:

import org.json.simple.JSONObject;

class json{

static{
    System.loadLibrary("json");
}

private native void json(JSONObject j);

public static void main(String args[]){
    json js = new json();
    JSONObject j = new JSONObject();
    j.put("name","someone");
    j.put("age", 15);
    js.json(j);

}
}
如何在c中访问这些数据

#include<stdio.h>
#include<jni.h>
#include "json.h"
#include "cJSON.h"

JNIEXPORT void JNICALL Java_json_json(JNIEnv *env, jobject obj, jobject j){


return;
}
#包括
#包括
#包括“json.h”
#包括“cJSON.h”
JNIEXPORT void JNICALL Java_json_json(JNIEnv*env,jobject obj,jobject j){
返回;
}
我找不到任何关于如何从c中的jobject访问json数据的参考。
我是jni的新手。还有其他方法吗?

通过JNI从C代码访问JSON数据与通过Java访问JSON数据没有太大区别。在Java中,您可以编写:

System.out.println("name = " + j.get("name"));
System.out.println("age = " + j.get("age"));
C代码基本上是一样的,只是更详细,因为

  • 您需要让类对象对它们调用方法
  • 您需要为传递到
    get
  • 您必须将从
    j.get(“name”)
    获得的
    jstring
    转换为C字符串
  • 使用后必须释放该字符串
  • 您必须手动取消对得到的
    java.lang.Integer
    的装箱
  • 下面的代码就是这样做的:

    #include<stdio.h>
    #include<jni.h>
    #include "json.h"
    // Notice that "cJSON.h" is not needed
    
    JNIEXPORT void JNICALL Java_json_json(JNIEnv *env, jobject obj, jobject json) {
    
        // Get the Class object for JSONObject.
        jclass JSONObjectClass = (*env)->GetObjectClass(env, json);
    
        // Get the ID of the "get" method that we must call.
        // Notice that due to type erasure, both the parameter and the return value
        // are just plain Objects in the type signature.
        jmethodID getID = (*env)->GetMethodID(env, JSONObjectClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
        if (getID == NULL) return;
    
        // Create java.lang.String instances for the keys we pass to j.get.
        jstring nameKey = (*env)->NewStringUTF(env, "name");
        jstring ageKey = (*env)->NewStringUTF(env, "age");
        if (nameKey == NULL || ageKey == NULL) return;
    
        // Actually get the name object. Since we know that the value added
        // in the Java code is a string, we just cast the jobject to jstring.
        jstring name = (jstring) (*env)->CallObjectMethod(env, json, getID, nameKey);
        if (name == NULL) return;
    
        // Get a C string that can be used with the usual C functions.
        const char *name_cstr = (*env)->GetStringUTFChars(env, name, NULL);
        if (name_cstr == NULL) return;
    
        printf("name = %s\n", name_cstr);
    
        // Once done, the string must be released.
        (*env)->ReleaseStringUTFChars(env, name, name_cstr);
        name_cstr = NULL;
    
        // Get the java.lang.Integer object representing the age.
        jobject ageObj = (*env)->CallObjectMethod(env, json, getID, ageKey);
        if (ageObj == NULL) return;
    
        // Unbox the java.lang.Integer manually.
        jclass IntegerClass = (*env)->GetObjectClass(env, ageObj);
        jmethodID intValueID = (*env)->GetMethodID(env, IntegerClass, "intValue", "()I");
        if (intValueID == NULL) return;
    
        jint age = (*env)->CallIntMethod(env, ageObj, intValueID);
    
        printf("age = %d\n", (int) age);
    }
    
    #包括
    #包括
    #包括“json.h”
    //请注意,不需要“cJSON.h”
    JNIEXPORT void JNICALL Java_json_json(JNIEnv*env,jobject obj,jobject json){
    //获取JSONObject的类对象。
    jclass JSONObjectClass=(*env)->GetObjectClass(env,json);
    //获取我们必须调用的“Get”方法的ID。
    //注意,由于类型擦除,参数和返回值
    //只是类型签名中的普通对象。
    jmethodID getID=(*env)->GetMethodID(env,JSONObjectClass,“get”,“(Ljava/lang/Object;)Ljava/lang/Object;”;
    if(getID==NULL)返回;
    //为传递给j.get的键创建java.lang.String实例。
    jstringnameKey=(*env)->NewStringUTF(env,“name”);
    jstringagekey=(*env)->NewStringUTF(env,“age”);
    if(nameKey==NULL | | ageKey==NULL)返回;
    //实际上得到了name对象。因为我们知道
    //在Java代码是字符串的情况下,我们只是将jobject强制转换为jstring。
    jstring name=(jstring)(*env)->CallObjectMethod(env,json,getID,nameKey);
    if(name==NULL)返回;
    //获取一个可以与常用C函数一起使用的C字符串。
    const char*name_cstr=(*env)->GetStringUTFChars(env,name,NULL);
    if(name_cstr==NULL)返回;
    printf(“name=%s\n”,name\u cstr);
    //完成后,必须释放字符串。
    (*env)->发布StringUTFChars(环境、名称、名称);
    name_cstr=NULL;
    //获取表示年龄的java.lang.Integer对象。
    jobject-ageObj=(*env)->CallObjectMethod(env、json、getID、ageKey);
    if(ageObj==NULL)返回;
    //手动取消绑定java.lang.Integer。
    jclass IntegerClass=(*env)->GetObjectClass(env,ageObj);
    jmethodID intValueID=(*env)->GetMethodID(env,IntegerClass,“intValue”,“()I”);
    if(intValueID==NULL)返回;
    jint age=(*env)->CallIntMethod(env,ageObj,intValueID);
    printf(“年龄=%d\n”,(int)年龄);
    }
    
    更复杂的使用是以同样的方式完成的:检查您将在Java中编写什么,并找到一种使用相同值在C中使用相同方法调用相同方法的方法