Java和JNA为C函数传递params

时间:2017-04-19 15:15:46

标签: java c pointers jna

我正在使用JNA从C DLL调用函数:

extern _declspec( dllexport )
int ReadCP(IN OUT unsigned char* Id, IN OUT unsigned int* Size);

在Java中,我使用这种方法为JNA使用接口:

int ReadCP(byte[] id, IntByReference size);

我成功加载DLL并以这种方式调用方法:

byte[] id= new byte[10];
IntByReference size = new IntByReference();
IMimicDLL demo = (IMimicDLL) Native.loadLibrary("MyLib", IMimicDLL.class);
size.setValue(10);
//....
while(true){
  demo.ReadCP(id, size);
  //...
}

循环id中的第一次具有正确的值,但即使逻辑应该更改它也保持相同的值。可能是什么问题?那与指针有关吗?

2 个答案:

答案 0 :(得分:3)

id的映射错误:您无法通过JNA将原始数组作为参数传递。

您应该更改界面以使用Pointer

int ReadCP(Pointer id, IntByReference size);

然后你会为id:

分配本机端内存
Pointer id = new Memory(10);

从函数传递并检索id后,您将从本机内存中获取字节数组:

byte[] idByteArray = id.getByteArray(0, 10);

other get*() methods for Pointer,例如getString(),可能会或可能不会更适用于您尝试获取的Id字段的最终类型。< / p>

至于值重复一次但不是在重复调用之后,这听起来好像在某个时刻系统正在拍摄&#34;快照&#34;当前的硬件状态,你必须找到一种刷新该快照的方法。故障排除步骤包括:

  • 清除数组/指针中的数据,看看它是否从C端DLL重新填充(问题不在你的JNA中,而是使用DLL)。
  • 在整个过程中检查您的size变量,以确保它保持您期望的值10。可能的是,当您移除卡时它可能返回0,然后如果您尝试读取新值(长度为0),则不会覆盖旧数组超过索引0。
  • 替代首先使用哪张卡。
  • 替换启动程序,加载和交换卡片的顺序,以收集有关该过程的哪一步似乎导致该值粘附的数据。
  • 调查DLL以获取&#34;刷新&#34;或者&#34;重新加载&#34;硬件状态的快照。
  • 在循环之间尝试unloading and reloading the DLL

在使用JNA时,大多数这些步骤超出了您的问题的范围,并且需要您提供有关我们用于帮助我们进一步帮助的DLL的更多信息。

答案 1 :(得分:0)

这里是while循环中的业务登录

while(true){ 
 try { 
   Thread.sleep(1500); 
 } catch (InterruptedException e1) 
 { 
   e1.printStackTrace();
 } 
if(demo.cardPresent() == 0 && read == false){
 demo.ReadCP(id, size);
 try { 
System.out.println(" -- id : " + new String(id.getByteArray(0, 10),"UTF-8"));
 read = true;
 continue; 
} catch (Exception ex) {
 ex.printStackTrace();
 }
}else if(demo.cardPresent() != 0){
read = false;
}