如何在 JNI 中调用 String.getBytes()?我想在 JNI 中获取字节数组,但 CallByteMethod 只是 returns jbyte 而不是 jbytearray
How to I call String.getBytes() in JNI? I want to get byte array in JNI but the CallByteMethod just returns jbyte and not the jbytearray
我正在尝试调用 String.getBytes()
方法从字符串对象获取 JNI 中的字节数组。 JNI 有 CallByteMethod
、CallByteMethodV
和 CallByteMethodA
方法,其中 return 是 jbyte,但它没有 return 一个 java 字节数组的方法。
我试过调用 CallByteMethod
方法,但出现错误
JNI DETECTED ERROR IN APPLICATION: use of deleted local reference 0xd5ec7fe1
我尝试的其他代码是使用像这样的 jbytearray 转换
jbyteArray keyBytes = (jbyteArray)(*env)->CallByteMethod(env, stringValue, getBytesMId);
因为 IDE 显示警告
Taking pointer from integer without a cast.
但后来我收到一个不同的错误
JNI DETECTED ERROR IN APPLICATION: the return type of CallByteMethod does not match 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");
}
从您的代码中发现一些错误:
下一行是错误的:
jstring stringValue = "test";
它应该如下所示:
jstring stringValue = (*env)->NewStringUTF(env, "test");
用CallObjectMethod
得到jbyteArray
,记得把return类型转换成jbyteArray
。见下文:
jbyteArray keyBytes = (jbyteArray)(*env)->CallObjectMethod(env, stringValue, getBytesMId);
下面是显示预期结果的屏幕截图。
完整来源:
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");
我正在尝试调用 String.getBytes()
方法从字符串对象获取 JNI 中的字节数组。 JNI 有 CallByteMethod
、CallByteMethodV
和 CallByteMethodA
方法,其中 return 是 jbyte,但它没有 return 一个 java 字节数组的方法。
我试过调用 CallByteMethod
方法,但出现错误
JNI DETECTED ERROR IN APPLICATION: use of deleted local reference 0xd5ec7fe1
我尝试的其他代码是使用像这样的 jbytearray 转换
jbyteArray keyBytes = (jbyteArray)(*env)->CallByteMethod(env, stringValue, getBytesMId);
因为 IDE 显示警告
Taking pointer from integer without a cast.
但后来我收到一个不同的错误
JNI DETECTED ERROR IN APPLICATION: the return type of CallByteMethod does not match 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");
}
从您的代码中发现一些错误:
下一行是错误的:
jstring stringValue = "test";
它应该如下所示:
jstring stringValue = (*env)->NewStringUTF(env, "test");
用
CallObjectMethod
得到jbyteArray
,记得把return类型转换成jbyteArray
。见下文:jbyteArray keyBytes = (jbyteArray)(*env)->CallObjectMethod(env, stringValue, getBytesMId);
下面是显示预期结果的屏幕截图。
完整来源:
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");