java - 无法正确调用 .dll 函数
问题描述
我正在使用 JNA Java 调用一个共享的 .dll 函数。从文档中,可以调用该函数以使用 Visual C++ 接收参数,如下所示;
PMSifEncodeKcdLcl(PCHAR ff, PCHAR Dta, BOOL Dbg, PCHAR szOpId, PCHAR szOpFirst, PCHAR szOpLast);
从文档:
- ff - 单个 ASCII 字符。
- Dta - 指向一个以 null 结尾的字符串。
- Dbg - 一个布尔标志
- szOpId - 指向一个以 null 结尾的字符串
- szOpFirst - 指向一个以 null 结尾的字符串
- szOpLast - 指向一个以 null 结尾的字符串
该字符串由多个数据字段构建而成。字符串中每个数据字段的格式如下:
- RS FI 数据
RS = 记录分隔符。
指示数据字段的开始。单个 ASCII 记录分隔符 [RS] 字符(十六进制 1E)
FI = 字段标识符 - 指示字段中的数据类型。单个 ASCII 字符。
数据= 实际数据。多个 ASCII 字符,取决于字段标识符。有时数据的长度是可变的。以下字段的记录分隔符指示数据字段的结尾(或对于最后一个字段,字符串末尾的 NULL 字符)。
在ff字段中返回一个应答代码。在字段Dta中返回答案数据(如果有)
我已经交叉检查了 JNA 文档以确认字段映射,但仍然没有成功。经过几天的尝试。我想出了下面的代码;
我的 Java 代码:
/* JNA interface class
*/
public class JNALocksInterface {
public interface LockLibrary extends StdCallLibrary {
LockLibrary INSTANCE = (LockLibrary) Native.loadLibrary("path_to_dll", LockLibrary.class);
public void PMSifEncodeKcdLcl(byte[] ff, byte[] dta, boolean debug, String szOpid, String szOpFirst, String szOpLast);
}
}
/*My Calling Class Code*/
JNALocksInterface.LockLibrary INSTANCE = JNALocksInterface.LockLibrary.INSTANCE;
String dta = "*R101*L101*TSingle Room*NMatu*FZachary*URegular Guest*D201805021347*O201805030111";
String ff = "A";
byte[] dataBytes = new byte[dta.length() + 1];
System.arraycopy(dta.getBytes("UTF-8"), 0, dataBytes, 0, dta.length());
dataBytes[dta.length()] = 0;
byte[] dtaByteArray = new byte[dta.length() + 1];
byte[] ffByteArray = ff.getBytes("UTF-8");
for (int i = 0; i < dataBytes.length; i++) {
String s1 = String.format("%8s", Integer.toBinaryString(dataBytes[i] & 0xFF)).replace(' ', '0');
// System.out.println(s1);
if((char)dataBytes[i] == '*')
{
dtaByteArray[i] = 30;
}
else{
int val = Integer.parseInt(s1, 2);
byte b = (byte) val;
dtaByteArray[i] = b;
}
}
byte[] commandCodeFinal = new byte[1];
for (int i = 0; i < ffByteArray.length; i++) {
String s2 = String.format("%8s", Integer.toBinaryString(ffByteArray[i] & 0xFF)).replace(' ', '0');
System.out.println(s2);
int val = Integer.parseInt(s2, 2);
byte b = (byte) val;
commandCodeFinal[i] = b;
}
String userNameBytes = "test";
String userFirstNameBytes = "test";
String userLastNameBytes = "test";
INSTANCE.PMSifEncodeKcdLcl(commandCodeFinal, dtaByteArray, false, userNameBytes, userFirstNameBytes, userLastNameBytes);
我在字段 ff 和 dta 上得到了错误的响应,如下所示。
FF Response >> :
DTA Response >> 0101IR101L101TSingle RoomNMatuFZacharyURegular GuestD201805021347O2018050
我用 ascii 记录分隔符替换“*”。
有人可以告诉我如何使用 JNA 正确调用该函数吗?我已经搜索了所有但仍然没有成功。
解决方案
解决了它。使用了 Unicode 字段分隔符并使用了 JNA 内存对象,它成功了!
也在使用 WINdows 10 64 位。更改为 Windows 7 32 位,它工作!
用下面的代码片段替换了代码;
String fieldSeparator = "\u001e"
String dataTest = fieldSeparator+"R101"+fieldSeparator+"TSingle Room"+fieldSeparator+"FShujaa"+fieldSeparator+"NMatoke"
+ fieldSeparator+"URegular Guest"+fieldSeparator+"D201805040842"+fieldSeparator+"O201805051245";
String dataTestPadded = org.apache.commons.lang.StringUtils.rightPad(dataTest,30,'0');
System.out.println("Padded string >> " + dataTestPadded);
String data = dataTest;
//getPayloadToSend(payLoadSample) + (char)00;
String commandCode = "A";
Memory commandCodeMemory = new Memory(commandCode.length()+1);
commandCodeMemory.setString(0, commandCode);
Memory dataMemory = new Memory(data.length()+1);
dataMemory.setString(0, data);
//dataMemory.setString(1, "0");
System.out.println("Registerring >> " + INSTANCE.PMSifRegister("42860149", "BatchClient")) ;
INSTANCE.PMSifEncodeKcdLcl(commandCodeMemory, dataMemory, false, "ZKMATU", "zACHARY", "tESTING");
System.out.println("FF Response >> " + commandCodeMemory.getString(0));
System.out.println("DTA Response >> " + dataMemory.getString(0));
INSTANCE.PMSifUnregister();
推荐阅读
- github - 在 Github 操作脚本中检查数组中的元素
- reactjs - 如何让你的material-ui网格变成拖放元素
- java - 使用 java 客户端从 Kubernetes 命名空间中删除轮廓 httpproxy
- r - 使用 CEM 和 MatchIt R 包的不同结果
- mysql - 设置 lower_case_table_names 后无法启动 MySQL 8.0.12
- reactjs - reactjs 中 ng-init 的等价物
- python - Pyspark DF groupBy 给出错误 - TypeError: 'NoneType' object is not iterable
- python - os.getcwd() 找不到当前工作目录
- javascript - 在本机反应中不断收到“无法解析模块”
- apache-spark - 在 log4j.properties 文件中使用 %throwable 的异常 Stacktrace 日志未完全加载