使用JNI中的GetDirectBufferAddress

我试图了解如何从JNI层使用GetDirectBufferAddress 。 要理解我构建了一个非常简单的例子:

 public class my_image_info { static { System.loadLibrary("my_jni"); } private java.nio.ByteBuffer image_info_bb; native static void initc( java.nio.ByteBuffer bb ); my_image_info() { image_info_bb = java.nio.ByteBuffer.allocateDirect( 5 * 4 ); initc( image_info_bb ); } public java.nio.ByteBuffer getBB() { return image_info_bb; } static public void main(String argv[]) { my_image_info fii = new my_image_info(); java.nio.ByteBuffer bb = fii.getBB(); System.out.println("1: " + bb.getInt(0)); System.out.println("2: " + bb.getInt(4)); System.out.println("3: " + bb.getInt(8)); System.out.println("4: " + bb.getInt(12)); System.out.println("5: " + bb.getInt(16)); } 

然后从本机JNI层:

 JNIEXPORT void JNICALL Java_my_1image_1info_initc (JNIEnv *env, jclass cls, jobject jobj) { int *iBuf = (*env)->GetDirectBufferAddress(env, jobj); iBuf[0] = -2; iBuf[1] = -1; iBuf[2] = 0; iBuf[3] = 1; iBuf[4] = 2; } 

如果我用openjdk在这里运行这个例子(debian / linux wheezy amd64):

 $ java -version java version "1.6.0_34" OpenJDK Runtime Environment (IcedTea6 1.13.6) (6b34-1.13.6-1~deb7u1) OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode) 

这是我看到的:

 1: -16777217 2: -1 3: 0 4: 16777216 5: 33554432 

我理解索引2和3的值。但是所有其他值对我没有任何意义,我会期望类似:

 1: -2 2: -1 3: 0 4: 1 5: 2 

我从JNI中的ByteBuffer用法中误解了什么?

我从文档中遗漏的是,默认情况下java.nio.ByteBuffer实际上使用的是BIG_ENDIAN字节顺序。 这解释了我在LITTLE_ENDIAN系统上看到的行为。 见这里的参考。

我的代码现在读作:

 image_info_bb = java.nio.ByteBuffer.allocateDirect( 5 * 4 ); image_info_bb.order( java.nio.ByteOrder.LITTLE_ENDIAN ); 

看来默认情况下它始终是BIG_ENDIAN ,并且到目前为止还没有为LITTLE_ENDIAN提供API,如此处的错误报告中所述(JDK-5043362:(bf)NewDirectByteBuffer始终具有订单ByteOrder.BIG_ENDIAN)。