以前,我使用JNA(4.1.0)来访问为32位系统编译的SiUSBXp.dll
,并且它在32位JVM上运行良好。
我最近将操作系统升级到64位Windows 7,我现在使用64位JVM(jdk1.8.0_151)运行与64位版本的本机DLL相同的旧Java程序。但是,通过USB发送和接收数据库时,我遇到了一些问题。
有时,Java应用程序会提供"无效的内存访问权限"例外
有时,在使用-134127606
3
而不是IntByReference
醇>
我从未在32位版本上遇到过这些问题。我使用C ++应用程序测试了64位DLL,它没有任何问题。 此外,我尝试过使用JNA 4.5.0,但它仍然提供了"无效的内存访问"异常。
这是导致问题的C ++函数:
SI_STATUS SI_Write (
HANDLE Handle,
LPVOID Buffer,
DWORD NumBytesToWrite,
DWORD *NumBytesWritten,
OVERLAPPED *o = NULL
);
在Java中,我已尝试过这两种声明,但它们在32位版本上运行良好。
int SI_Write (HANDLE Handle, byte[] lpBuffer, int dwBytesToWrite, IntByReference lpdwBytesWritten);
int SI_Write (HANDLE Handle, Pointer lpBuffer, int dwBytesToWrite, IntByReference lpdwBytesWritten);
在Java中调用此函数的示例:
int dwBytesWritten = 0;
int size = 3;
byte[] buf_w= new byte[size];
IntByReference IBR_BytesWritten = new IntByReference();
IBR_BytesWritten.setValue(dwBytesWritten);
buf_w[0] = FT_WRITE_MSG;
buf_w[1] = (byte)(size & 0x000000FF);
buf_w[2] = (byte)((size & 0x0000FF00) >> 8);
Pointer ptr = new Memory(buf_w.length);
ptr.write(0, buf_w, 0, buf_w.length);
status = SiUSBXp.INSTANCE.SI_Write(dev_handle_ref.getValue(), ptr, size, IBR_BytesWritten);
此代码工作几次然后使用IBR_BytesWritten.getValue()给无效内存访问或返回错误值 另外,我尝试直接使用send byte []代替Pointer并提出相同的问题
提前致谢
解决方案
使用此签名解决了问题
int SI_Write (HANDLE Handle, byte[] lpBuffer, int dwBytesToWrite, IntByReference lpdwBytesWritten, Pointer overlapped);
我用 NULL 作为最终参数调用该函数,它将空指针传递给函数。即使它采用C库中的默认值= NULL