简体   繁体   English

在使用 JNI 将 c++ unordered_map 返回到 java 之前将其转换为 java hashMap

[英]Converting a c++ unordered_map to java hashMap before returning it to java using JNI

I have a very large c++ unordered_map on android platform I would like to return this as a hashMap in java using JNI.我在 android 平台上有一个非常大的 c++ unordered_map我想使用 JNI 将它作为 java 中的 hashMap 返回。

extern "C" JNIEXPORT jobject JNICALL Java_quantum_QUANTUM_getMessage(JNIEnv *env, jobject thisObj, jdoubleArray bbox) {

    unordered_map<int, Foo> Map;
    Map = getData(filename, bbox);

    // convert Map to java object
    // return java object
}

I am quite new to JNI.我对 JNI 很陌生。 I haven't found any helpful material on how to do this.我还没有找到任何关于如何做到这一点的有用材料。

I tried the approach in the link below but I am getting a lot of compilation errors on this.我尝试了下面链接中的方法,但我在这方面遇到了很多编译错误。

how to correctly send a std::map<> from C++ to Java through JNI? 如何通过 JNI 将 std::map<> 从 C++ 正确发送到 Java?

Another suggestions was to pass an empty javaHashmap over JNI and populate it.另一个建议是通过 JNI 传递一个空的 javaHashmap 并填充它。 But I am not sure on how to do that.但我不确定如何做到这一点。 what is the better solution?什么是更好的解决方案?

It will require some tweaking.这将需要一些调整。 You can do it by creating Map object inside C++ or by passing Map from Java to C++ and filling it there.您可以通过在C++创建Map对象或将MapJava传递到C++并在那里填充来实现。

Basically, what you need is to:基本上,您需要的是:

  1. create HashMap创建HashMap
  jclass mapClass = env->FindClass("java/util/HashMap");
  if(mapClass == NULL) {
    return NULL;                  // alternatively, throw exception (recipeNo019)
  }

  jobject hashMap = env->NewObject(mapClass, mapConstructorID);
  if(hashMap == NULL) {
    return NULL;                  // as above
  }
  1. making sure to embed your primitive types inside object (eg you can embed int inside Integer )确保将原始类型嵌入到对象中(例如,您可以将int嵌入到Integer
  jclass integerClass = env->FindClass("java/lang/Integer");
  if(integerClass == NULL) {
    return NULL;                  // alternatively, throw exception (recipeNo019)
  }

  jmethodID integerConstructorID = env->GetMethodID(integerClass, "<init>", "(I)V");
  if(integerConstructorID == NULL) {
    return NULL;
  }

  ...
  ...

  jobject key = env->NewObject(integerClass, integerConstructorID, pair.first);
  1. filling HashMap with data用数据填充HashMap
  for (auto const& pair: map) {
    jobject key = env->NewObject(integerClass, integerConstructorID, pair.first);
    jobject value = env->NewObject(integerClass, integerConstructorID, pair.second);
    if(key == NULL || value == NULL) {
      return NULL;
    }
    env->CallObjectMethod(hashMap, putMethodID, key, value);
  }

That's it.就是这样。 You can find full sample code here:您可以在此处找到完整的示例代码:

https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo047 https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo048 https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo047 https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo048

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM