使用来自JNI的GetDirectBufferAddress

我正在尝试GetDirectBufferAddress从JNI层了解如何使用。为了理解,我构建了一个非常简单的示例:

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,并没有努力已经取得迄今提供的API

LITTLE_ENDIAN,如bug报告解释这里(JDK-5043362(BF)NewDirectByteBuffer总是有秩序ByteOrder.BIG_ENDIAN)。


文档最近已更新,以反映以下内容:

  • JDK-8225152:发行说明:JNI NewDirectByteBuffer创建直接缓冲区java.nio.ByteOrder.BIG_ENDIAN

以上是 使用来自JNI的GetDirectBufferAddress 的全部内容, 来源链接: utcz.com/qa/430389.html

回到顶部