1

我是 Java 和 JNA 的新手。我正在使用 JNA 从 Java 加载和使用本机 DLL 函数。

我在将指针传递给数组时遇到问题。根据规范,我从 Java 填充这个数组并尝试将指向这个数组的指针发送到 DLL。

这就是本机调用的外观,

StartCom(UNUM8 *pCoPData)
From the spec: pCoPData -> Reference of the buffer holding the data

对应的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.

有什么建议有很大帮助吗?请告诉我。提前谢谢了 !

4

1 回答 1

1

当您在输入中传递不正确类型的函数时,为什么会期望得到正确的结果?

如果函数需要一个指向一个或多个 8 位元素的指针(byte在 Java 中,本机代码中大概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[]用作UNUM8*参数,而不是分配和初始化Memory.

于 2012-10-13T15:14:36.147 回答