无法调用.dll函数correclty

时间:2018-05-03 13:16:51

标签: java dll jna

我使用JNA Java调用共享的.dll函数。从文档中,可以调用该函数以使用Visual C ++接收参数,如下所示;

PMSifEncodeKcdLcl(PCHAR ff, PCHAR Dta, BOOL Dbg, PCHAR szOpId, PCHAR szOpFirst, PCHAR szOpLast);

来自doc:

  • ff - 单个ASCII字符。
  • Dta - 指向以null结尾的字符串。
  • 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

我正在替换&#34; *&#34;使用ascii记录分隔符。

有人可以告诉我如何使用JNA正确调用该函数吗?我已经搜遍过,但仍然没有成功。

1 个答案:

答案 0 :(得分:0)

解决了IT问题。使用了Unicode字段分隔符并使用了JNA Memory对象并且工作了!

还使用了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();