Accessing the JSON data from the C code via JNI is not much different from accessing it via Java. In Java you would write:
System.out.println("name = " + j.get("name"));
System.out.println("age = " + j.get("age"));
The C code is basically the same, just much more verbose, since
- You need to get the class object to call methods on them
- You need to construct
jstring instances for the keys passed to get
- You must convert the
jstring you get from j.get("name") to a C string
- You must release that string after use
- You must manually unbox the
java.lang.Integer that you get
The code below does just that:
#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);
}
More complicated use is done the same way: Check what you would write in Java, and find a way to call the same methods with the same values in C using the JNI functions.