JNI - java ArrayList转换为c ++ std :: string *

时间:2014-06-25 08:06:53

标签: java c++ string arraylist java-native-interface

我正在尝试使用c ++中的JNI进行数据转换。我使用 java 字符串 字符串时遇到了麻烦,因为我无法将这样的数据转换成 c ++ vector std :: string *

我想知道如果可能的话,如何在不牺牲太多性能的情况下进行转换。任何想法,将不胜感激。

2 个答案:

答案 0 :(得分:10)

我不知道这是否符合您的性能要求,但这可能是一个良好的开端。

对于这两个选项,假设jobject jList;是您的ArrayList。

选项1

将List转换为数组并迭代数组(如果你有LinkedList而不是ArrayList,可能更适用)

// retrieve the java.util.List interface class
jclass cList = env->FindClass("java/util/List");

// retrieve the toArray method and invoke it
jmethodID mToArray = env->GetMethodID(cList, "toArray", "()[Ljava/lang/Object;");
if(mToArray == NULL)
    return -1;
jobjectArray array = (jobjectArray)env->CallObjectMethod(jList, mToArray);

// now create the string array
std::string* sArray = new std::string[env->GetArrayLength(array)];
for(int i=0;i<env->GetArrayLength(array);i++) {
    // retrieve the chars of the entry strings and assign them to the array!
    jstring strObj = (jstring)env->GetObjectArrayElement(array, i);
    const char * chr = env->GetStringUTFChars(strObj, NULL);
    sArray[i].append(chr);
    env->ReleaseStringUTFChars(strObj, chr);
}

// just print the array to std::cout
for(int i=0;i<env->GetArrayLength(array);i++) {
    std::cout << sArray[i] << std::endl;
}

选项2

另一种方法是使用List.size()List.get(int)方法从列表中检索数据。当您使用ArrayList时,此解决方案也可以,因为ArrayList是RandomAccessList。

// retrieve the java.util.List interface class
jclass cList = env->FindClass("java/util/List");

// retrieve the size and the get method
jmethodID mSize = env->GetMethodID(cList, "size", "()I");
jmethodID mGet = env->GetMethodID(cList, "get", "(I)Ljava/lang/Object;");

if(mSize == NULL || mGet == NULL)
    return -1;

// get the size of the list
jint size = env->CallIntMethod(jList, mSize);
std::vector<std::string> sVector;

// walk through and fill the vector
for(jint i=0;i<size;i++) {
    jstring strObj = (jstring)env->CallObjectMethod(jList, mGet, i);
    const char * chr = env->GetStringUTFChars(strObj, NULL);
    sVector.push_back(chr);
    env->ReleaseStringUTFChars(strObj, chr);
}

// print the vector
for(int i=0;i<sVector.size();i++) {
    std::cout << sVector[i] << std::endl;
}

_edited:用NULL_
替换JNI_FALSE _edited:用push_back _替换插入_

答案 1 :(得分:3)

你也可以在JNI中使用经典的java迭代器,同时优化ArrayListLinkedList的循环。

jobject jIterator = env->CallObjectMethod(jList, env->GetMethodID(env->GetObjectClass(jList), "iterator", "()Ljava/util/Iterator;"));
jmethodID nextMid = env->GetMethodID(env->GetObjectClass(jIterator), "next", "()Ljava/lang/Object;");
jmethodID hasNextMid = env->GetMethodID(env->GetObjectClass(jIterator), "hasNext", "()Z");

while (env->CallBooleanMethod(jIterator, hasNextMid)) {
    jobject jItem = env->CallObjectMethod(jIterator, nextMid);
    /* do something with jItem */
}