我是Java和JNA的新手。我正在使用JNA从Java加载和使用本机DLL函数。
我在向数组传递指针时遇到问题。根据规范,我从Java填充此数组并尝试将指向此数组的指针发送到DLL。
这是本机通话的外观,
StartCom(UNUM8 *pCoPData)
From the spec: pCoPData -> Reference of the buffer holding the data
Correspoding JNA Mapping,
int[] buf = new int[2];
buf[0] = 0x1A;
buf[1] = 0x10;
Pointer pCoPData = new Memory(8);
pCoPData.write(0, buf, 0, buf.length);
Library.INSTANCE.StartCom(pCoPData);
当我执行上面的代码时,我从dll日志中注意到只使用了数组0x1A的第一个元素而忽略了第二个字节。 DLL始终只看到数组的第一个元素。
我假设可能只有2个可能发生此问题,
1. The above approach I have taken to populate and send the address of a Java array to the DLL is incorrect.
2. The DLL is expecting a UNUM8* whereas I am sending a UNUM32*. I will try with byte[] instead of int[] and see if there is any difference.
任何建议都有很大帮助?请告诉我。非常感谢提前!
答案 0 :(得分:1)
为什么在输入时传递函数错误类型时,您期望得到正确的结果?
如果函数期望指向Java中的一个或多个8位元素(byte
,可能UNUM8
在本机代码中是8位),那么你需要传递相当于指向一个或多个8位元素的指针。您正在向使用两个32位元素初始化的内存传递指针。以下是8位与32位情况下的内存(所有值均代表8位字节):
将两个8位值写入内存后:
base+0x0: 0x1A
base+0x1: 0x10
将两个32位值写入内存后:
base+0x0: 0x1A 0x00 0x00 0x00
base+0x4: 0x10 0x00 0x00 0x00
因此,您可以看到,如果本机代码从base
开始读取,则它看到的值会根据您初始化内存的方式而有很大差异。
顺便说一句,如果本机代码不需要保留对传入的内存的引用,而不是函数调用本身,则可以使用byte[]
作为{{1 }}参数,而不是分配和初始化UNUM8*
。