2011-09-24 107 views
1

据我所知,我不能从C++中调用从Java字符串数组返回的方法,所以只有解决这个问题的方法是循环调用方法,它将返回一个数组元素,但是如何将它们存储在C++数组中?如何从C++调用Java方法(java返回String [])?

在Java我有方法:

public static String getData(int index){ return arry[index]; } 

和在C++:

char * args[10]; 
for (int i = 0; i < arrayLength; i ++) { 
    jmethodID mid = env->GetStaticMethodID(INF.cls_JSox, "getData",(I)Ljava/lang/String;"); 
    jobject result = env->CallStaticObjectMethod(cls, mid, num, i); 
    const char *nativeString = env->GetStringUTFChars((jstring) result, 0); 
    const size_t len = strlen(nativeString); 
    cout << "copying... \n"; 
    strncpy(args[i], nativeString, len); 
    env->ReleaseStringUTFChars((jstring)result, nativeString); 
} 

但当i = 1我发现了存储器冲突错误在Java中。我怎样才能正确地从收到的字符串中复制数据到char * args[10]?从Java传递的每个字符串的长度约为3-5个字符。

+0

绝对有可能使用JNI来调用返回字符串数组的Java方法。 –

+0

'GetStaticMethodID'中的'INF.cls_JSox'是否与CallStaticObjectMethod中的'cls'指向相同的类? – jogabonito

回答

4

假设您发布的C++代码片段已完成,您将获得访问冲突,因为在将值复制到其中之前需要分配args[i] - args[i] = new char[ len + 1 ]会执行此操作。

实际上,你可以从C++返回一个Java字符串数组调用一个方法,假设你的方法是:

public static String[] getData() { return array; } 

然后在本地方面,你应该能够做这样的事情:

jmethodID method = env->GetStaticMethodID(cls, "getData", "()[Ljava/lang/String;"); 
jarray data = (jarray) env->CallStaticObjectMethod(cls, method); 

// assumption: the result of getData() is never null 
jsize const length = env->GetArrayLength(data); 

// assumption: the String[] is always of length > 0 
char** args = new char*[ length ]; 

for(jsize index(0); index < length; ++index) 
{ 
    jstring element = (jstring) env->GetObjectArrayElement(array, index); 

    // assumption: there are no null strings in the array 
    char const* nativeString = env->GetStringUTFChars(element, 0); 
    jsize const nativeLength = strlen(nativeString); 

    args[index] = new char[ nativeLength + 1 ]; 
    strncpy(args[index], nativeString, nativeLength); 

    env->ReleaseStringUTFChars(element, nativeString); 
} 

我还没有试过编译上面的代码片段,所以可能有一两个错误,但它应该是一个好的起点。我已经使用char *数组和本地字符串离开了代码,因此在某些时候代码将不得不在数组的每个成员和数组本身上调用delete[]。使用std::vectorstd::string作为内存管理的最终结果可能会更简单,这取决于提供的字符串将如何使用。