如何从C++调用Java方法(Java返回String[])?

3
据我所知,我无法从C++调用返回Java字符串数组的方法,因此唯一的解决方案是循环调用方法,逐个返回数组元素,但是如何将它们存储在C++数组中呢?
在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个字符。


完全可以使用JNI调用返回字符串数组的Java方法。 - Stuart Cook
在“GetStaticMethodID”中,“INF.cls_JSox”是否指的是“CallStaticObjectMethod”中的“cls”类? - bobby
1个回答

6
假设你贴出的 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( data, 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 );
    env->DeleteLocalRef( element );
}

我还没有尝试编译上述代码片段,可能会有一两个错误,但它应该是一个可以开始的不错的起点。我已经保留了使用char*数组和本地字符串的代码,所以最终代码将需要对数组中的每个成员和数组本身调用delete[]方法进行内存释放。根据提供的字符串使用方式,最终可能更简单的做法是使用std::vectorstd::string来进行内存管理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接