Я вызываю разделяемую функцию .dll, используя JNA Java. Из документации можно вызвать функцию для получения параметров с использованием Visual C ++, как показано ниже;
PMSifEncodeKcdLcl(PCHAR ff, PCHAR Dta, BOOL Dbg, PCHAR szOpId, PCHAR szOpFirst, PCHAR szOpLast);
Из документа:
- ff - один символ ASCII.
- Dta - указывает на строку с нулевым символом в конце.
- Dbg - логический флаг
- szOpId - указывает на строку с нулевым символом в конце
- szOpFirst - указывает на строку с нулевым символом в конце
- szOpLast - указывает на строку с нулем в конце
Строка состоит из нескольких полей данных. Формат для каждого поля данных в строке следующий:
- Данные 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? Я искал по всему, но до сих пор не удалось.