java - 从 JNI 使用 GetDirectBufferAddress

标签 java c java-native-interface

我试图了解如何从 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));
}

然后从 native 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 系统上看到的行为。参见引用 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)。


最近更新了文档以反射(reflect):

关于java - 从 JNI 使用 GetDirectBufferAddress,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38709377/

相关文章:

c - 在 realloc 中使用结构值会导致段错误

c - 如何检查点 (x,y) 是否在笛卡尔坐标系中的多边形内?

android - 没有找到 native/UnsatisfiedLinkError 的实现让我抓狂

java - JNI——多线程

java - 将 ConfigurationProperties 绑定(bind)到 <Enum,Pojo> 的映射

java - 小服务程序 : Cannot forward after response has been committed

c - 没有指针的指针错误

java - JNI 不满意链接错误 : A dynamic link library (DLL) initialization routine failed

java - 如何使用 Perl 识别对 Java 类的引用?

java - 确定 onPause() 是由用户导航触发还是由我的 Activity 启动另一个 Activity 触发