代码之家  ›  专栏  ›  技术社区  ›  snaggs

如何将Java映射转换为cocos2d ValueMap?

  •  2
  • snaggs  · 技术社区  · 7 年前

    简短问题:

    我如何转换 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

    ValueMap 从…起 jobject项目 ?

    cocos2d::ValueMap myData = ... ???
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Oo.oO    7 年前

    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替换为两个数组对象。这样,可以删除大量代码。

    看看这里( recipeNo038 )对于替代方法:

    这一次,我们传递了两个字符串数组。它们的对齐方式是,相应的索引包含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;
    
    }