首页 > 解决方案 > 无法正确调用 .dll 函数

问题描述

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

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

从文档:

该字符串由多个数据字段构建而成。字符串中每个数据字段的格式如下:

在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 正确调用该函数吗?我已经搜索了所有但仍然没有成功。

标签: javadlljna

解决方案


解决了它。使用了 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();

推荐阅读