Using GetDirectBufferAddress from JNI
c, java, java-native-interface
Solution
What I missed from the documentation is that by default `java.nio.ByteBuffer` is actually using `BIG_ENDIAN` byte order. Which explains the behavior I was seeing on my `LITTLE_ENDIAN` system. See ref here.
My code now reads as:
image_info_bb = java.nio.ByteBuffer.allocateDirect( 5 * 4 );
image_info_bb.order( java.nio.ByteOrder.LITTLE_ENDIAN );
It appears that by default it is always `BIG_ENDIAN`, and no effort has been made so far to provide an API for `LITTLE_ENDIAN`, as explained in the bug report here (JDK-5043362 : (bf) NewDirectByteBuffer always has order ByteOrder.BIG_ENDIAN).
Documentation has been updated recently to reflect that:
- JDK-8225152 : Release Note: JNI NewDirectByteBuffer Creates Direct Buffer That Is java.nio.ByteOrder.BIG_ENDIAN
Problem
I am trying to understand how to use `GetDirectBufferAddress` from the JNI layer. To understand I've build a very simple example: ``` 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)); } ``` And then from the native JNI layer: ``` 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; } ``` If I run this example over here (debian/linux wheezy amd64) with openjdk : ``` $ 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) ``` Here is what I see: ``` 1: -16777217 2: -1 3: 0 4: 16777216 5: 33554432 ``` I understand the values for index 2 & 3. But all other values do not make any sense to me, I would have expected something like: ``` 1: -2 2: -1 3: 0 4: 1 5: 2 ``` What did I misunderstood from the `ByteBuffer` usage in JNI?