如何将uint8_t *转换为jbyteArray jni android

时间:2018-05-17 00:03:05

标签: java android java-native-interface

我正在开发一个使用一些c / c ++代码的Android库。

我显然有某种编码错误,只会在运行时发生错误。

错误:JNI DETECTED ERROR IN APPLICATION: use of invalid jobject 0x7d61e62000

这是我用来调用C代码的JNI代码。

JNIEXPORT jbyteArray JNICALL
Java_com_comp_complibrary_api_initializeProduct(JNIEnv *env, jobject 
                                                    instance,
                                                    jbyteArray buffer_) {
    jbyte *buffer = env->GetByteArrayElements(buffer_, NULL);

    jbyteArray rv = (jbyteArray) initializeProduct((uint8_t *) buffer);

    env->ReleaseByteArrayElements(buffer_, buffer, 0);

    return rv;
}

initializeProduct会返回uint8_t *

如果我理解正确,那么我应该能够将返回值强制转换为jbyteArray,然后能够将其分配给我的一个java类中的byte[]。但事实并非如此。

byte[] defend = (byte[]) initializeProduct(bufferByteArray);

当我将jbyteArray作为参数传递给uint8_t *时,您会注意到initializeProduct可以投放到uint8_t *。单步执行c代码,我可以确认这是真的。

jbyteArray转换/投放到const payload = { apple: 1, dog: 2, cat: 3 } 的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

你不是。它不是一个铸造操作。您必须使用NewByteArray()创建一个Java字节数组对象,并通过SetByteArrayRegion()使用原始C数据设置元素。

  

您会注意到jbyteArray可以转换为uint8_t *,因为我将其作为参数传递给initializeProduct()

Non sequitur。仅仅因为你可以施展某些东西并不意味着它实际上变成了那样。您需要使用GetByteArrayElements()GetByteArrayRegion()jbyteArray获取C代码的数据,然后在完成后进行相应的ReleaseXXX()调用。

答案 1 :(得分:0)

铬源中类似的代码:ToJavaByteArray(),希望这些代码可以为您提供帮助。

ScopedJavaLocalRef<jbyteArray> ToJavaByteArray(JNIEnv* env,
                                               const uint8_t* bytes,
                                               size_t len) {
  jbyteArray byte_array = env->NewByteArray(len);
  CheckException(env);
  DCHECK(byte_array);
  env->SetByteArrayRegion(
      byte_array, 0, len, reinterpret_cast<const jbyte*>(bytes));
  CheckException(env);
  return ScopedJavaLocalRef<jbyteArray>(env, byte_array);
}