2017-04-19 56 views
0

我使用JNA调用从C DLL中的函数:Java和JNA的C函数传递PARAMS

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有一个正确的值,但即使逻辑应该改变它也保持相同的值。可能是什么问题?这与指针有关吗?

回答

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字段的最终类型。

至于值更新一次但不是重复调用后,这听起来像在某些时候系统正在对当前硬件状态“快照”,你必须找到一种方法来刷新该快照。故障排除步骤包括:

  • 清除数组/指针中的数据并查看它是否从C端DLL重新填充(问题不在于您的JNA使用DLL)。
  • 在整个过程中检查您的size变量以确保它保持您期望的值10。当你删除卡片时,它可能会返回0,然后如果你尝试读取一个新值(长度为0),你不会覆盖索引0之后的旧数组。
  • 替代先使用哪张卡片。
  • 替代程序的启动顺序,加载和交换卡片以收集过程的哪一步看起来会导致值停滞的数据。
  • 调查DLL以查找“刷新”或“重新加载”硬件状态快照的方法。
  • 在循环之间尝试unloading and reloading the DLL

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

+0

感谢您的回答业务登录,但我仍然有同样的问题:在while循环我有应该阅读卡ID的逻辑,我得到了即使我换了卡,同样的第一张卡的ID,** ID **不会改变。 –

+0

这就是我所能提供的所有Java/JNA组件所能提供的帮助。是否有更多的文档可用于DLL方法? –

+0

这是我在while循环逻辑 '而(真){ \t \t \t \t尝试{ \t \t \t \t \t了Thread.sleep(1500); \t \t \t \t}赶上(InterruptedException的E1){ \t \t \t \t \t e1.printStackTrace(); \t \t \t \t} \t \t \t \t如果(demo.cardPresent()== 0 &&读==假){ \t \t \t \t \t demo.ReadCP(ID,大小); \t \t \t \t \t尝试{ \t \t \t \t \t \t的System.out.println(” - 编号: “+新的字符串(id.getByteArray(0,10),” UTF-8" )); \t \t \t \t \t \t read = true; \t \t \t \t \t \t continue; \t \t \t \t \t}赶上(例外){ \t \t \t \t \t \t ex.printStackTrace(); \t \t \t \t \t} \t \t \t \t}否则如果(!demo.cardPresent()= 0){ \t \t \t \t \t读取= FALSE; \t \t \t \t} \t \t \t}' –

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; 
}