如何在JNI中调用String.getBytes()方法?我想在JNI中获取字节数组,但是CallByteMethod只返回jbyte而不是jbytearray。

3
我正在尝试从一个字符串对象中调用String.getBytes()方法,在JNI中获取字节数组。JNI有CallByteMethodCallByteMethodVCallByteMethodA方法,可以返回jbyte,但没有返回Java字节数组的方法。
我尝试了调用CallByteMethod方法,但是出现了错误:

JNI检测到应用程序中的错误:使用已删除的本地引用0xd5ec7fe1

我尝试的另一种代码是使用jbytearray的强制转换,像这样:
jbyteArray keyBytes = (jbyteArray)(*env)->CallByteMethod(env, stringValue, getBytesMId);

因为IDE显示了一条警告

从整数中取指针,没有进行强制转换。

但接下来我又得到了一个不同的错误信息,它说:

JNI在应用程序中检测到错误:CallByteMethod的返回类型与byte[] java.lang.String.getBytes()不匹配

下面是我的代码:

JNIEXPORT jstring JNICALL
Java_net_jni_test_MainActivity_callTest(JNIEnv *env, jobject instance) {

    jstring stringValue = "test";

    jclass stringClass = (*env)->FindClass(env, "java/lang/String");
    jmethodID getBytesMId = (*env)->GetMethodID(env, stringClass, "getBytes", "()[B");

    jbyteArray keyBytes = (*env)->CallByteMethod(env, stringValue, getBytesMId);

    return (*env)->NewStringUTF(env, "1111");
}

2
你需要调用 CallObjectMethod()CallByteMethod() 用于返回 byte 的方法。 - user207421
1个回答

4

发现您的代码中有一些错误:

  1. Below line is wrong:

    jstring stringValue = "test";
    

    And it should be like below:

    jstring stringValue = (*env)->NewStringUTF(env, "test");
    
  2. Use CallObjectMethod to get the jbyteArray, remember to cast the return type to jbyteArray. See below:

    jbyteArray keyBytes = (jbyteArray)(*env)->CallObjectMethod(env, stringValue, getBytesMId);
    
  3. Below is a screenshot showing the expected result.

    enter image description here

完整源码:

JNIEXPORT jstring JNICALL
Java_net_jni_test_MainActivity_callTest(JNIEnv *env, jobject instance) {
    jstring stringValue = (*env)->NewStringUTF(env, "test");

    jclass stringClass = (*env)->FindClass(env, "java/lang/String");
    jmethodID getBytesMId = (*env)->GetMethodID(env, stringClass, "getBytes", "()[B");

    jbyteArray keyBytes = (jbyteArray)(*env)->CallObjectMethod(env, stringValue, getBytesMId);

    // determine the needed length and allocate a buffer for it
    jsize num_bytes = (*env)->GetArrayLength(env, keyBytes);


    // obtain the array elements
    jbyte* elements = (*env)->GetByteArrayElements(env, keyBytes, NULL);
    if (!elements) {
        // handle JNI error ...
    }

    for(int i = 0; i < num_bytes; i++) {
        char ch = elements[i];
        ALOGI("arrayLength: %c", ch);
    }

    // Do not forget to release the element array provided by JNI:
    (*env)->ReleaseByteArrayElements(env, keyBytes, elements, JNI_ABORT);
}

请注意C++ JNI和C JNI之间的区别。例如,C风格的JNI具有以下方法约定:
jmethodID getBytesMId = (*env)->GetMethodID(env, stringClass, "getBytes", "()[B");

但C++就像下面这样:
jmethodID getBytesMId = env->GetMethodID(stringClass, "getBytes", "()[B");

很高兴看到它有所帮助! - shizhen

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