我正在尝试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)。
文档最近已更新,以反映以下内容:
问题内容: 我们的游戏引擎本身可以在android上本地运行。我们需要从调用某些Java函数通过的。 为了进行调用,我们从此处(GitHub)使用JNIHelper.h / cpp: JniHelper.h,JniHelper.cpp 例如,此C ++代码: 理想情况下,我们希望所有这些调用都发生在上,并在函数调用完成后将an 作为参数传递给参数,并再次使用返回值进行调用。 调用函数的理想方法:
我不明白这是什么意思,也不明白为什么只有有时候才会发生。如有任何帮助,我们将不胜感激。很乐意分享更多细节。 我们已经能够在Android7.0设备上重现这次崩溃。但并不一致。
问题内容: 我需要使用某些Java类中包含的逻辑。我找到了JNI,但该项目似乎最近没有更新。 有没有办法在Delphi本机应用程序中使用它?我使用Delphi 2009。 问题答案: 比JNI更新的解决方案是JNA,它还支持(Delphi)DLL的回调。我发现它易于使用。
问题内容: 与JNI相比,JNA似乎更易于调用本机代码。在什么情况下,您将在JNA上使用JNI? 问题答案: JNA不支持c 类的映射,因此,如果您使用的是c 库,则需要一个jni包装器 如果需要大量内存复制。例如,您调用一个返回大字节缓冲区的方法,对其中的内容进行更改,然后需要调用使用此字节缓冲区的另一种方法。这将需要您将该缓冲区从c复制到java,然后再将其从java复制回到c。在这种情况下,
线程名称:线程组1-1示例开始时间:2019-09-11 18:52:42英国夏令时加载时间:0连接时间:0延迟时间:0大小以字节为单位:0发送字节:0头大小以字节为单位:0主体大小以字节为单位:0示例计数:1错误计数:1数据类型(“text”“bin”“”):文本响应代码:000响应消息:javax.naming.nameNotFoundException:DynamicQueue/MyQueu
我可以编译(带有一个我不理解的警告),但是我在尝试运行程序时得到一个ClassNotFoundException。 知道我做错了什么吗?