![](/img/trans.png)
[英]Why is the ciphertext 32 bytes long when encrypting 16 bytes with AES?
[英]Why do I need to reserve more than 4 bytes for a JNA pointer to receive a long when sizeof(long) is 4?
我正在使用JNA与使用Visual Studio 2015编译的本机C库进行通信。我正在使用64位计算机。 我试图通过长指针long *pdays
参数来接收C函数的值。 我收到以下异常:
java.lang.IndexOutOfBoundsException:界限超出了可用空间:com.sun.jna.Memory.boundsCheck(Memory.java:220)的大小为com.sun.jna.Memory.boundsCheck(Memory.java:220)的offset = 8(Memory.java: 498)
我不明白我在这里缺少什么,如果我只为指针保留4个字节的内存,则会导致上面的崩溃,但是,如果我保留8个,一切都会很好。 但是sizeof(long)返回4,那么为什么我需要保留4个以上的字节?
System.out.println(NativeLong.SIZE); // --> 4
System.out.println(Native.LONG_SIZE); // --> 4
// Pointer pDays = new Memory(Native.LONG_SIZE); Results in IndexOutOfBoundsException
Pointer pDays = new Memory(8); //
nativeLib.GetDaysUntilExpiration(pDays);
return pDays.getLong(0); // crashes here when reserving just 4 bytes
它崩溃是因为您试图从仅分配了4个字节的本机内存中读取8个字节。
原生类型是什么,还是只有4个字节都没有关系。 Memory
仅包含4个字节,您可以按照自己希望的任何方式进行解释。 您可能会得到一个byte[]
数组,或者一个int
(具有这4个字节),或者甚至是一个short
或byte
只能读取该数量的字节。 您甚至可以尝试使用String
(尽管没有空终止符,但您读取的内容可能远远超过允许的4个字节,而且谁知道您会得到什么,因此很危险。)
您已经要求获取一个Java long
为8字节的变量。 因此,代码将检查偏移量的下8个字节是否适合分配的内存。 来自Memory.java
的代码具有以下硬编码:
boundsCheck(offset, 8);
javadoc清楚为什么会这样:
间接指向
malloc
空间的本地指针laPointer.getLong
。 但是此方法执行边界检查,以确保该间接操作不会导致访问已分配空间之外的malloc
。
在不手动分配空间的情况下,执行操作的正确方法是仅使用NativeLongByReference
。 JNA会自行负责空间的分配和值的获取,您不必担心本机的大小。
NativeLongByReference pDays = new NativeLongByReference();
nativeLib.GetDaysUntilExpiration(pDays);
return pDays.getValue().longValue();
编辑:我在您的注释中注意到您说“ C函数参数是一个指针,使用NativeLongByReference将导致” LongByReference无法转换为Pointer” –这不是C函数的问题,但与JNA映射有关在您的界面中,最好将GetDaysUntilExpiration
的JNA映射更改为NativeLongByReference
参数,如果您不能更改该函数的JNA映射,则可以使用pDays.getPointer()
作为参数来解决。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.