Доступ к данным JSON из кода C через JNI не сильно отличается от доступа к ним через Java. На Java вы бы написали:
System.out.println("name = " + j.get("name"));
System.out.println("age = " + j.get("age"));
Код на C в основном такой же, только более многословный, так как
- Вам нужно получить объект класса для вызова методов на них
- Вам необходимо создать
jstring
экземпляров для ключей, переданных get
- Вы должны преобразовать
jstring
, полученное из j.get("name")
в строку 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);
}
Более сложное использование выполняется аналогичным образом: проверьте, что вы написали бы на Java, и найдите способ вызывать одни и те же методы с одинаковыми значениями в C, используя функции JNI .