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

How to access JSON data passed to c in jni?

我的 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;
}

我找不到任何关于如何在 c 中从 jobject 访问 json 数据的参考资料。 我是 jni 的新手。还有其他方法吗?

通过 JNI 从 C 代码访问 JSON 数据与通过 Java 访问数据没有太大区别。在 Java 你会写:

System.out.println("name = " + j.get("name"));
System.out.println("age = " + j.get("age"));

C 代码基本相同,只是更加冗长,因为

  1. 您需要获取 class 对象才能调用它们的方法
  2. 您需要为传递给 get
  3. 的键构造 jstring 个实例
  4. 您必须将从 j.get("name") 获得的 jstring 转换为 C 字符串
  5. 您必须在使用后释放该字符串
  6. 您必须手动拆箱您收到的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);
}

更复杂的使用以相同的方式完成:检查您将在 Java 中编写的内容,并找到一种使用 JNI functions.[] 在 C 中调用具有相同值的相同方法的方法。 =18=]