2016-07-26 82 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接口。 –