2

在 java 中,我使用 JNA 加载 VC++ dll 文件并在其中调用函数,在一个函数中我需要发送 6 个参数,在 VC++ 函数定义中,我得到前 3 个参数的正确值,但后 3 个参数的值为“0”,
第二个参数是字节数组,当我发送 1024 个字节时,我得到第 5 个布尔参数为,但当我传递 10 个字节时,它被视为
我的函数原型:

int deviceupload(Pointer p, _byte[] data_, long startaddress, long datalength,_Boolean rt_,Pointer xyz);

那么映射会根据参数的大小而改变吗?
或者 JNA 堆栈太小以至于不能容纳 6 个参数?但是根据 JNA 文档MAX_NARGSFunction类值是 256 所以我认为 6 个参数不是问题,
即使第 3 和第 4 个参数具有相同的数据类型,在 VC++ 函数定义startaddress中被正确接收但datalength接收到的值为 0

,所以知道为什么它的行为如此奇怪吗?

4

2 回答 2

1

实际上我的问题已经解决了,VC++ 函数期望 long 是 4 字节,但是在 java 中我传递的是 8 字节的 long,但是根据 JNA文档VC++ long 等价于 Java 中的 NativeLong,但我们不能减去两个 NativeLong 变量我应该这样做。所以我通过了Long。

但后来我在 VC++int中为 (4bytes) 参数在 java 中传递了 (4bytes) 参数,然后它工作正常,但我不明白为什么其他参数受到影响,因为我的 que 中以前的参数数据类型未匹配,因为变量数据类型未匹配变量数据是生效了,所以我的问题仍然没有答案,任何人都可以帮助我理解它吗?,不幸的是只有我的错误被清除了long



startaddressdatalength

于 2012-12-20T12:34:18.203 回答
0

参数被放置在堆栈上的内存“槽”中。一个小参数可能占用一个槽,或与另一个参数共享一个槽,而一个大参数可能占用两个槽。您可以看到,如果您将一个小参数误认为是一个大参数,它将如何将所有后续参数转移到不正确的位置。

无效 my_func(int32 p1,int64 p2)

|               |
+---------------+
| P2 (64-bit)   |
+---------------+
| P2            | (P2 takes up two slots)
+---------------+
+ P1 (32-bit)   |
+---------------+ <-- Top of stack

现在,如果您错误地为 P1 使用了 64 位值,则会得到以下信息:

|               |
+---------------+
| P2 (64-bit)   |
+---------------+
| P2            | 
+---------------+
+ P1 (64-bit)   |
+---------------+ 
+ P1            |
+---------------+ <-- Top of stack

被调用者(你调用的函数)不知道这种转变已经发生,因此试图从它们的预期位置读取参数。对于小的论点,它可能会得到一个更大的论点,而对于更大的论点,它可能会得到两个或多个其他论点的片段。

被调用者实际看到的是:

|               |
+---------------+
| (P2)          | 
+---------------+
+ (P1)          |
+---------------+ 
+ (P1)          |
+---------------+ <-- Top of stack

您可以看到为 P1 读取的值实际上只是较大值的一半,而为 P2 读取的值包括 P1 的另一半和作为 P2 传入的值的一半。

(这个解释有些简化,但通常表明堆栈是如何工作的)

于 2012-12-21T12:39:24.560 回答