2016-07-26 273 views
2

我想将C++映射传递给Java,不知道如何定义返回参数,以便该方法有效。我没有麻烦的字符串或整型作为返回参数,但我不能让地图工作。
我的Java方法是这样的:将C++ map转换为jobject JNI?

private native Map<String,String> sayHello(); 

我的C++代码是:

#include <stdio.h> 
#include "stdafx.h" 
#include "jni.h" 
#include "HelloJNI.h" 
#include <utility> 
#include <map> 
#include <string.h> 
#include <iostream> 

using namespace std; 

JNIEXPORT jobject JNICALL Java_HelloJNI_sayHello 
(JNIEnv *, jobject) 
{ 
    map<string, string> mMap; 
    mMap["1"] = "Ladi"; 
    mMap["2"] = "Dida"; 
    return mMap; 
} 

,当然我得到一个错误,告诉我,我必须转换MMAP以某种方式jobject。但我不知道如何做到这一点。

我希望它没有双重职位,我只是发现一些问题处理传输名单。

在此先感谢。

+0

一个独立的问题,但是在你的方法的任何实现中,一个独立的问题是哪个字符编码在'mMap'中使用字符串。使用'.c_str()'的代码假定数据不包含NUL字符。并且使用'NewStringUTF'的代码假定编码(或者至少与预期的数据一样)可以被解释为_modified_ UTF-8。 –

回答

4

您需要使用jni api来查找HashMap java类,然后使用它的构造和插入元素的方法。然后添加所有元素,最后返回这个地图。它应该看起来如下(警告 - 伪代码!!!)

env->PushLocalFrame(256); // fix for local references 

jclass hashMapClass= env->FindClass(env, "java/util/HashMap"); 
jmethodID hashMapInit = env->GetMethodID(env, hashMapClass, "<init>", "(I)V"); 
jobject hashMapObj = env->NewObject(env, hashMapClass, hashMapInit, mMap.size()); 
jmethodID hashMapOut = env->GetMethodID(env, hashMapClass, "put", 
      "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 

for (auto it : mMap) 
{ 
    env->CallObjectMethod(env, hashMap, put, 
     env->NewStringUTF(it->first.c_str()), 
     env->NewStringUTF(it->second.c_str())); 
} 

env->PopLocalFrame(hashMap); 

return hashMap; 

ps。我通常在android下编码jni,但上面的代码应该在其他平台下工作。

+3

不错。但我认为简单地将一个空的'HashMap'对象传递给本地代码并调用'put'方法会更容易,就像'private native void sayHello(Map jmap);' –

+0

@mrtnj感谢您的快速回答。我会试试今天,让你知道如果我能得到它:) AndrewHenle多数民众赞成在一个不错的主意,我认为这将是更容易的另一种解决方案,但问题是在我的程序中,地图必须是在调用本机java函数之前填充值。但是,无论如何感谢队友! –

+0

@AndrewHenle是的。将一些JNI内容移回到Java通常不太容易出错。 “私人本地”方法是要走的路。不过,“公共”方法应该有一个自然的Java接口。 –