将Java中的byte []传递给C到JNI中的函数:如何使用jarraybyte

blu*_*ech 32 c java java-native-interface

这是我第一次使用JNI,也是我第一次在C中写一些行.

我想要做的很简单.我只是尝试使用C例程切换byte []的endiannes.

在java中,它是这样完成的:

public void switchEndianness(byte[] array){

        byte byte1;
        byte byte2;

        for(int i = 0; i < array.length ; i+=2){
            byte1 = array[i];
            byte2 = array[i+1];

            array[i] = byte2;
            array[i+1] = byte1;
        }
}
Run Code Online (Sandbox Code Playgroud)

所以为了使用JNI做到这一点,我试图在JNICALL中使用相同的例程,但是它没有编译.到目前为止我写的是这样的:

JNIEXPORT void JNICALL Java_CEndianness_switchEndianness(JNIEnv *env, jobject obj, jbyteArray array, jint offset, jint length){

    char byte1;
    char byte2;

    int i;
    for(i = offset; i  < length ; i+=2){
        byte1 = array[i];
        byte2 = array[i+1];

        array[i] = byte2;
        array[i+1] = byte1;
    }
}
Run Code Online (Sandbox Code Playgroud)

我不知道如何使用jbyteArray类型的数据.是否可以将jbyte存储在char中?另一个问题是..当这个例程结束时... java中的byte []会被修改吗?或者它只在C调用内修改?

任何帮助???

谢谢大家!

qrt*_*tt1 50

你可以通过GetByteArrayElements得到jbyte*:

jbyte* bufferPtr = (*env)->GetByteArrayElements(env, array, NULL);
Run Code Online (Sandbox Code Playgroud)

知道数组的长度很重要:

jsize lengthOfArray = (*env)->GetArrayLength(env, array);
Run Code Online (Sandbox Code Playgroud)

拥有jbyte*和length,你可以用c-array做所有的事情.最后,释放它:

(*env)->ReleaseByteArrayElements(env, array, bufferPtr, 0);
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果可能,建议使用`(*env) - > ReleaseByteArrayElements(env,array,bufferPtr,JNI_ABORT);`.最后一个参数意味着JVM不会尝试将字节从bufferPtr复制回Java数组.通常,您知道C函数不会更改数组. (13认同)
  • 如果您使用的是C++而不是C,则语法略有不同.您不需要取消引用env,也不需要将其作为参数传递.例如,bufferPtr = env-> GetByteArrayElements(array,NULL). (8认同)

Jas*_*run 8

qrtt给了你很好的答案.

但是,JNI具有非常全面且(相对)易于理解的文档,如果您将来再次使用JNI功能,则应该从前面阅读.你可以在这里找到它:http: //docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html

对于您的特定情况,这里是关于处理数组的部分:http: //docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html#wp1265

  • 没有人从前到后阅读文档. (13认同)
  • 当我学习JNI时,我会从前到后阅读文档.这非常有帮助. (5认同)
  • url再次更改:http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html (2认同)
  • 是的,但是StackOverflow的目的不是要使人们指向文档。目的是提供答案并包括指向文档的链接作为参考。 (2认同)