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

发布于 2024-12-06 04:53:43 字数 956 浏览 0 评论 0原文

据我所知,我无法从 C++ 调用从 Java 字符串数组返回的方法,因此唯一的解决方案是循环调用方法,该方法将按 1 返回数组元素,但如何将它们存储在 C++ 数组中?

在 Java 中,我有 method:

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 个字符。

As far as I know I can't call method from C++ that will return from Java string array, so only solution for this is loop call method that will return array elements on by one, but how can I store them in C++ array?

In Java I have method:

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

and in 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);
}

but when i = 1 I'm getting memory violation error in Java. How can I correctly copy data from received strings to the char * args[10]? The length of every string passed from Java is about 3-5 chars.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

っ左 2024-12-13 04:53:43

假设您发布的 C++ 代码片段是完整的,您将遇到访问冲突,因为您需要在将值复制到其中之前分配 args[i] - a 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 进行内存管理最终可能会更简单,具体取决于所提供的字符串的使用方式。

Assuming that the C++ code snippet you posted is complete, you are getting an access violation because you need to allocate args[i] before copying a value into it - a args[i] = new char[ len + 1 ] would do.

You can actually call a method from C++ that returns a Java string array, assume your method was:

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

Then on the native side you should be able to do something like:

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 );
}

I haven't tried to compile the above snippet so there might be an error or two, but it should be an ok starting point. I've left the code using a char* array and native strings, so at some point the code is going to have to call delete[] on each member of the array and on the array itself. It may end up ultimately simpler using std::vector and std::string for memory management depending on how the supplied strings are going to be used.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文