Как получить доступ к данным JSON, переданным в c в jni? - PullRequest
2 голосов
/ 25 июня 2019

Моя 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 из jobject в c.Я новичок в Jni.Есть ли другой способ сделать это?

1 Ответ

0 голосов
/ 25 июня 2019

Доступ к данным JSON из кода C через JNI не сильно отличается от доступа к ним через Java. На Java вы бы написали:

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

Код на C в основном такой же, только более многословный, так как

  1. Вам нужно получить объект класса для вызова методов на них
  2. Вам необходимо создать jstring экземпляров для ключей, переданных get
  3. Вы должны преобразовать jstring, полученное из j.get("name") в строку C
  4. Вы должны освободить эту строку после использования
  5. Вы должны вручную распаковать 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 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...