如何将Java Map转换为cocos2d ValueMap

How to convert Java Map to cocos2d ValueMap?

本文关键字:cocos2d ValueMap 转换 Map Java      更新时间:2023-10-16

简短的问题:

如何将jobject转换为cocos2d::ValueMap

详细问题:

我有Java部分:

public class MyCallback implements MyListener {
    public native void callback(Object data);
    public MyCallback(){}
    @Override
    public void onResponse(Map<String, String> data) {
        callback(data);
    }
}

我想将地图数据返回到 Cocos2d 类。所以我写道:

JNIEXPORT void JNICALL Java_com_comp_ MyCallback_ callback
    (JNIEnv *env, jobject obj, jobject data) {

我得到jobject data

那么现在如何从jobject获得ValueMap

cocos2d::ValueMap myData = ... ???

HashMaps是必须访问才能获取内容的对象。因此,您面前的大量代码;)

看看下面:

#include <stdio.h>
#include "jni.h"
#include "recipeNo037_PassHashMap.h"
JNIEXPORT int JNICALL Java_recipeNo037_PassHashMap_displayHashMap
  (JNIEnv *env, jclass obj, jobject objarg) {
  /* Get objarg's class - objarg is the one we pass from
     Java */
  jclass clsHashMap = (*env)->GetObjectClass(env, objarg);
  /* Remember that you can alway get method signature using javap tool
     > javap -s -p java.util.HashMap | grep -A 1 key
         public java.util.Set<K> keySet();
           descriptor: ()Ljava/util/Set;
  */
  jmethodID midKeySet =
    (*env)->GetMethodID(env, clsHashMap, "keySet", "()Ljava/util/Set;");
  /* We have to make sure that method exists */
  if (midKeySet == NULL) {
    return -1; /* method not found */
  }
  /* Now, it's time for getting Set of keys */
  jobject objKeySet = (*env)->CallObjectMethod(env, objarg, midKeySet);
  /* Then, we can proceed to accessing keys */
  jclass clsSet = (*env)->GetObjectClass(env, objKeySet);
  /* The same story goes here - use javap to get propper descriptor
     > javap -s -p java.util.Set | grep -A 1 toArray
         public abstract java.lang.Object[] toArray();
           descriptor: ()[Ljava/lang/Object;
  */
  jmethodID midToArray =
    (*env)->GetMethodID(env, clsSet, "toArray", "()[Ljava/lang/Object;");
  if (midKeySet == NULL) {
    return -2; /* method not found */
  }
  jobjectArray arrayOfKeys = (*env)->CallObjectMethod(env, objKeySet, midToArray);
  int arraySize = (*env)->GetArrayLength(env, arrayOfKeys);
  for (int i=0; i < arraySize; i++)
  {
    jstring objKey = (*env)->GetObjectArrayElement(env, arrayOfKeys, i);
    const char* c_string_key = (*env)->GetStringUTFChars(env, objKey, 0);
    /* Once we have key, we can retrieve value for that key */
    jmethodID midGet =
      (*env)->GetMethodID(env, clsHashMap, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
    /* It's time to get Value for Key */
    jobject objValue = (*env)->CallObjectMethod(env, objarg, midGet, objKey);
    const char* c_string_value = (*env)->GetStringUTFChars(env, objValue, 0);
    printf("[key, value] = [%s, %s]n", c_string_key, c_string_value);
    (*env)->ReleaseStringUTFChars(env, objKey, c_string_key);
    (*env)->DeleteLocalRef(env, objKey);
    (*env)->ReleaseStringUTFChars(env, objValue, c_string_value);
    (*env)->DeleteLocalRef(env, objValue);
  }
  return 0;
}

有关完整的示例代码,请查看此处: recipeNo037

我个人会用两个数组对象替换HashMap。这样,可以删除大量代码。

看看这里(配方No038)的替代方法:

这一次,我们将传递两个字符串数组。它们的对齐方式是,相应的索引包含来自 HashMap 的键/值。这样,我们可以大大减少 C 中的代码,而 Java 中的开销并不大。

JNIEXPORT int JNICALL Java_recipeNo038_PassHashMap_displayHashMap
  (JNIEnv *env, jclass obj, jobjectArray keys, jobjectArray values) {
  /* We need to get array size. There is strong assumption that
     keys and values have the same length
  */
  int arraySize = (*env)->GetArrayLength(env, keys);
  /* For all elements in array, we will convert them to C based strings
  */
  for (int i=0; i < arraySize; i++)
  {
    /* First, we take key */
    jstring objKey = (*env)->GetObjectArrayElement(env, keys, i);
    const char* c_string_key = (*env)->GetStringUTFChars(env, objKey, 0);
    /* Then, we take the value value  */
    jobject objValue = (*env)->GetObjectArrayElement(env, values, i);
    const char* c_string_value = (*env)->GetStringUTFChars(env, objValue, 0);
    /* And we print some info for user */
    printf("[key, value] = [%s, %s]n", c_string_key, c_string_value);
    /* Make sure to release stuff */
    (*env)->ReleaseStringUTFChars(env, objKey, c_string_key);
    (*env)->DeleteLocalRef(env, objKey);
    (*env)->ReleaseStringUTFChars(env, objValue, c_string_value);
    (*env)->DeleteLocalRef(env, objValue);
  }
  return 0;
}