【问题标题】:change Byte[] values in JNI with android studio使用 android studio 更改 JNI 中的 Byte[] 值
【发布时间】:2019-04-22 13:41:19
【问题描述】:

我想在 JNI 函数中引用参数 Byte[] 并替换它们的值。
JNI 的声明如下。

public native void imageprocessing(long inputImage, long inputImage2, long outputImage, long outputImage2, Byte[] sim);

sim 是我想要改变的目标。
它的界面如下。

Java_com_example_duru_opencvtest_MainActivity_imageprocessing(JNIEnv *env, jobject 实例, jlong​​ inputImage, jlong​​ inputImage2, jlong​​ outputImage, jlong​​ outputImage2, jobjectArray sim)

它使用 jobjectArray 类型,我想将本地语言的 int 类型值放入 sim 对象中

所以我的方法是

        jbyteArray byte_array = env->NewByteArray(4);
        env->SetByteArrayRegion(byte_array, 0, 4, (jbyte*)tempSim);
        jobjectArray object_array = env->NewObjectArray(4, env->FindClass("java/lang/Byte"), byte_array);

        /* ERROR
        (*env).SetObjectArrayElement(sim, 0, (jobject)object_array[0]);
        (*env).SetObjectArrayElement(sim, 1, (jobject)object_array[1]);
        (*env).SetObjectArrayElement(sim, 2, (jobject)object_array[2]);
        (*env).SetObjectArrayElement(sim, 3, (jobject)object_array[3]);
        */     

tempSim 是 'int tempSim[4]' 并且 Sim 也有 4 个长度。

(*env).SetObjectArrayElement(sim, 0, (jobject)object_array[0]);

粗体部分出现语法错误比其他部分没有问题吗?

【问题讨论】:

  • 您无法从本机代码访问这样的 Java 数组。在这种情况下,您需要使用GetObjectArrayElement 函数。虽然我真的不明白byte_arrayobject_array 的目的是什么。为什么不直接将tempSim 的每个值传递给Byte.valueOf
  • 注意:NewByteArray 用于原始数组(Java:byte[];JNI:jbytearray),而不是对象数组(Java:Byte[])。

标签: java android java-native-interface native


【解决方案1】:
jclass javaLangByteClass = env->FindClass("java/lang/Byte");
jmethodID javaLangByteConstructor = env->GetMethodID(javaLangByteClass , "<init>", "(B)Ljava/lang/Byte;")
for (int i=0; i<3; i++) {
   jobject nextElement = env->NewObject(javaLangByteClass, javaLangByteConstructor, (jbyte)tempSim[i]);
   env->SetObjectArrayElement(sim, i, nextElement);
   env->DeleteLocalRef(nextElement);
}

请参阅下面的commentByte.valueOf() 可能比构造函数更有效:

jclass javaLangByteClass = env->FindClass("java/lang/Byte");
jmethodID javaLangByteStaticValueOf = env->GetStaticMethodID(javaLangByteClass , "valueOf", "(B)Ljava/lang/Byte;")
for (int i=0; i<3; i++) {
   jobject nextElement = env->CallStaticObjectMethod(javaLangByteClass, javaLangByteStaticValueOf, (jbyte)tempSim[i]);
   env->SetObjectArrayElement(sim, i, nextElement);
   env->DeleteLocalRef(nextElement);
}

【讨论】:

  • Byte.valueOf(byte) 通常应优先于 new Byte(byte),因为前者缓存了所有可能的 byte 值的 Byte 实例。
  • 如何在 JNI 中使用 Byte.valueof() ?我尝试了它,但没有任何效果。方法“Byte.valueof()”是否可以替换 javaLangByteConstructor 行?由于此语句发生运行时错误。
  • 感谢您的帮助,但jmethodID javaLangByteStaticValueOf = env-&gt;GetMethodID(javaLangByteClass , "valueOf", "(B)Ljava/lang/Byte;"); 仍然存在运行时错误我认为签名有问题,所以我更改了返回类型,Ljava/lang/Byte,到 String 因为它与返回类型参数类型相同很奇怪。但它没有用..
  • 抱歉,复制/粘贴错误。我们需要GetStaticMethodID()
猜你喜欢
  • 2014-02-01
  • 2017-03-06
  • 1970-01-01
  • 2015-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-11
相关资源
最近更新 更多