我试图了解如何使用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&的值。但是所有其他价值观对我来说都没有任何意义,我会期待类似的东西:
1: -2
2: -1
3: 0
4: 1
5: 2
我从JNI中的ByteBuffer用法中误解了什么?
答案 0 :(得分:8)
我从文档中遗漏的是默认情况下java.nio.ByteBuffer
实际上使用BIG_ENDIAN
字节顺序。这解释了我在LITTLE_ENDIAN
系统上看到的行为。请参阅参考here。
我的代码现在读作:
image_info_bb = java.nio.ByteBuffer.allocateDirect( 5 * 4 );
image_info_bb.order( java.nio.ByteOrder.LITTLE_ENDIAN );
默认情况下,它始终为BIG_ENDIAN
,并且目前尚无法为LITTLE_ENDIAN
提供API,如错误报告here(JDK-中所述) 5043362:(bf)NewDirectByteBuffer总是有订单ByteOrder.BIG_ENDIAN)。