JNA Data Returned to starts at 16th Byte expected

空扰寡人 提交于 2019-12-12 02:55:44

问题


The data I am expecting in the memory is

[8 Bytes (long)][20 Bytes (byte[20])][8 Bytes (long)][20 Bytes (byte[20])][8 Bytes(long)][20 Bytes (byte[20])]

And the data structures appear to be correct. The issue is the Data in the structures are wrong. The First byte of data expected is actually the 9th Byte.

The First 8 expected bytes do not appear at all (the native long)

I suspect the issue lies in the way I'm setting up my Java object but I am not seeing the issue, personally.

C Union:

union _My_SN {
    struct {
        unsigned long    sequence;           
        unsigned char     variant;           
        unsigned char    version;            
        unsigned short    pid;               
    } field;
    struct {
        unsigned long long    ser;
        unsigned char     serName [20]; //16 Characters followed by 4 \0 
        unsigned long long    hw;            
        unsigned char     hwName [20]; //16 Characters followed by 4 \0 
        unsigned long long    oem;           
        unsigned char     oemName [20]; //16 Characters followed by 4 \0
    } sn;
};

typedef union _My_SN My_SN;

JNA Java Representation

public class My_SN extends Union {

    public field_struct field;
    public sn_struct sn;

    public static class field_struct extends Structure {
        public NativeLong sequence;
        public byte variant;
        public byte version;
        public short pid;

        public field_struct() {
            super();
            setAlignType(ALIGN_NONE);
        }

        protected List getFieldOrder() {
            return Arrays.asList("sequence", "variant", "version", "pid");
        }

        public field_struct(NativeLong sequence, byte variant, byte version, short pid) {
            super();
            setAlignType(ALIGN_NONE);
            this.sequence = sequence;
            this.variant = variant;
            this.version = version;
            this.pid = pid;
        }

        public static class ByReference extends field_struct implements Structure.ByReference {
        };

        public static class ByValue extends field_struct implements Structure.ByValue {
        };
    };

    public static class sn_struct extends Structure {

        public long ser;
        public byte[] serName = new byte[20];
        public long hw;
        public byte[] hwName = new byte[20]; 
        public long oem;
        public byte[] oemName = new byte[20];

        public sn_struct() {
            super();
            setAlignType(ALIGN_NONE);
        }

        protected List getFieldOrder() {
            return Arrays.asList("ser", "serName", "hw", "hwName", "oem", "oemName");
        }

        public sn_struct(long ser, byte[] serName, long hw, byte[] hwName, long oem, byte[] oemName) {
            super();
            setAlignType(ALIGN_NONE);
            this.ser = ser;
            if (serName.length != this.serName.length) {
                throw new IllegalArgumentException("Wrong array size !");
            }
            this.serName = serName;
            this.hw = hw;
            if (hwName.length != this.hwName.length) {
                throw new IllegalArgumentException("Wrong array size !");
            }
            this.hwName = hwName;
            this.oem = oem;
            if (oemName.length != this.oemName.length) {
                throw new IllegalArgumentException("Wrong array size !");
            }
            this.oemName = oemName;
        }

        public static class ByReference extends sn_struct implements Structure.ByReference {
        };

        public static class ByValue extends sn_struct implements Structure.ByValue {
        };
    };

    public My_SN() {
        super();
        setAlignType(ALIGN_NONE);
    }

    public My_SN(sn_struct sn) {
        super();
        this.sn = sn;
        setAlignType(ALIGN_NONE);
        setType(sn_struct.class);
    }

    public My_SN(field_struct field) {
        super();
        setAlignType(ALIGN_NONE);
        this.field = field;
        setType(field_struct.class);
    }

    public static class ByReference extends My_SN implements Structure.ByReference {
    };

    public static class ByValue extends My_SN implements Structure.ByValue {
    };

}

For the output What i'm getting is

My_SN$sn_struct(allocated@0xf05c0e8 (84 bytes) (shared from allocated@0xf05c0e8 (84 bytes) (shared from allocated@0xf05bc90 (1200 bytes) (shared from auto-allocated@0xf05bc90 (9600 bytes))))) {
  long ser@0=3030343135303230
  byte serName[20]@8=[B@7fe6259a
  long hw@1c=33313841a8130e02
  byte hwName[20]@24=[B@5eaee30f
  long oem@38=ffffffffffffffff
  byte oemName[20]@40=[B@2bbd1e59
}

ser: "3472332698653045296"
serName: "00000009        $0  "
hw: "3688791424436997634"
hwName: "0E0215153024        "
oem: "-1"
oemName: "FFFFFFFFFFFFFFFF    "

memory dump
[30323035]
[31343030]
[30303030]
[30303039]
[00000000]
[00000000]
[24301515]
[020e13a8]
[41383133]
[30453032]
[31353135]
[33303234]
[00000000]
[00000000]
[ffffffff]
[ffffffff]
[46464646]
[46464646]
[46464646]
[46464646]
[00000000]

What Im Expecting to see (The C DLL doesnt print ser, hw, or oem but in the arrays):

Ser SN: 0205140000000009
H/W SN:     A8130E0215153024
OEM SN:     FFFFFFFFFFFFFFFF

This is the C code for this function:

__declspec(dllexport) Bool _cdecl
GetSN(
        DevProgramInfo           * pDevProgInfo,
        unsigned char              sessionID) {


    unsigned char                   * pCmd;
    unsigned short                    cmdLen = 0;
    Platform_Access_Get_SN_Payload     * pBufGetSN;

    pCmd = (unsigned char *)&Cmd;
    pBufGetSN = (Platform_Access_Get_SN_Payload *)&Payload;

    ClearMsgHeader((Message *)pCmd);

    Platform_Get_SN(pCmd, sessionID, &cmdLen, (unsigned char *)pBufGetSN);
    USBWriteToDevice(&pDevProgInfo->deviceInfo, pCmd, &cmdLen);
    USBReadFromDevice(&pDevProgInfo->deviceInfo, pCmd);
    Platform_Get_SN(pCmd, sessionID, &cmdLen, (unsigned char *)pBufGetSN);

    pDevProgInfo->sn.sn.ser = pBufGetSN->resp.ser;
    strcpy((char *)pDevProgInfo->sn.sn.serName, (char *)pBufGetSN->resp.serName);
    pDevProgInfo->sn.sn.hw = pBufGetSN->resp.hw;
    strcpy((char *)pDevProgInfo->sn.sn.hwName, (char *)pBufGetSN->resp.hwName);
    pDevProgInfo->sn.sn.oem = pBufGetSN->resp.oem;
    strcpy((char *)pDevProgInfo->sn.sn.oemName, (char *)pBufGetSN->resp.oemName);

    return TRUE;
}

Test Case?

__declspec(dllexport) bool _cdecl
StructTest(
    My_SN * snInfo){

        snInfo->sn.ser = 0x3030303030303030; //3030303030303030
        strcpy((char *)snInfo->sn.serName, "0123456789ABCDFFFFF"); //1234567890ABCDFFFFF\0
        snInfo->sn.hw = 0x3131313131313131; //11111111
        strcpy((char *)snInfo->sn.hwName, "0123456789ABCDFFFFF"); //1234567890ABCDFFFFF\0
        snInfo->sn.oem = 0x3232323232323232; //22222222
        strcpy((char *)snInfo->sn.oemName, "0123456789ABCDFFFFF"); //1234567890ABCDFFFFF\0

        printf("Ser: %llX\n",snInfo->sn.ser);
        printf("SerName: %s\n",snInfo->sn.serName);
        printf("hw: %llX\n",snInfo->sn.hw);
        printf("hwName: %s\n",snInfo->sn.hwName);
        printf("oem: %llX\n",snInfo->sn.oem);
        printf("oemName: %s\n",snInfo->sn.oemName);

        return My_TRUE;
}

OutPut

Ser: 3030303030303030
SerName: 0123456789ABCDFFFFF
hw: 3131313131313131
hwName: 0123456789ABCDFFFFF
oem: 3232323232323232
oemName: 0123456789ABCDFFFFF

JNA Call

boolean StructTest(My_SN snInfo);

public boolean testSNUnionStruct(My_SN snInfo){
    SHIPFlashProgrammerJNA sfpLibrary = SHIPFlashProgrammerJNA.INSTANCE;
    snInfo.setType(snInfo.sn.getClass());
    boolean result = sfpLibrary.StructTest(snInfo);



    System.out.println("Ser: \"" + Long.toHexString(snInfo.sn.ser) + "\"");
    System.out.println("SerName: \"" + new String(snInfo.sn.serName) + "\"");
    System.out.println("hw: \"" + Long.toHexString(snInfo.sn.hw) + "\"");
    System.out.println("hwName: \"" + new String(snInfo.sn.hwName) + "\"");
    System.out.println("oem: \"" + Long.toHexString(snInfo.sn.oem) + "\"");
    System.out.println("oemName: \"" + new String(snInfo.sn.oemName) + "\"");

    System.out.println(snInfo.toString(true));

    return result;
}

OUTPUT

Ser: "3030303030303030"
SerName: "0123456789ABCDFFFFF "
hw: "3131313100000000"
hwName: "11110123456789ABCDFF"
oem: "464646"
oemName: "222222220123456789AB"

My_SN(auto-allocated@0x1938e3d8 (84 bytes)) {
  My_SN$field_struct field@0=My_SN$field_struct(auto-allocated@0x1938dcb0 (8 bytes)) {
    NativeLong sequence@0=0
    byte variant@4=0
    byte version@5=0
    short pid@6=0
  }
  My_SN$sn_struct sn@0=My_SN$sn_struct(allocated@0x1938e3d8 (84 bytes) (shared from auto-allocated@0x1938e3d8 (84 bytes))) {
    long ser@0=3030303030303030
    byte serName[20]@8=[B@62e8c8
    long hw@1c=3131313100000000
    byte hwName[20]@24=[B@1a0df30
    long oem@38=464646
    byte oemName[20]@40=[B@9cf542
  }
}
memory dump
[30303030] //0000
[30303030] //0000
[30313233] //0123
[34353637] //4567
[38394142] //89AB
[43444646] //CDFF
[46464600] //FFF
[00000000] 
[31313131] //1111
[31313131] //1111
[30313233] //0123
[34353637] //4567
[38394142] //89AB
[43444646] //CDFF
[46464600] //FFF
[00000000]
[32323232] //2222
[32323232] //2222
[30313233] //0123
[34353637] //4567
[38394142] //89AB

来源:https://stackoverflow.com/questions/16405869/jna-data-returned-to-starts-at-16th-byte-expected

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!