问题
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