私がメモリに期待しているデータは
[8 Bytes (long)][20 Bytes (byte[20])][8 Bytes (long)][20 Bytes (byte[20])][8 Bytes(long)][20 Bytes (byte[20])]
そして、データ構造は正しいようです。問題は、構造内のデータが間違っていることです。期待されるデータの最初のバイトは、実際には9 番目のバイトです。
予想される最初の 8 バイトがまったく表示されない (ネイティブ long)
問題は Java オブジェクトの設定方法にあると思われますが、個人的には問題は見られません。
C ユニオン:
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 表現
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 {
};
}
出力について私が得ているのは
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]
私が期待していること(C DLLはser、hw、またはoemを出力しませんが、配列内にあります):
Ser SN: 0205140000000009
H/W SN: A8130E0215153024
OEM SN: FFFFFFFFFFFFFFFF
これは、この関数の C コードです。
__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;
}
テストケース?
__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;
}
出力
Ser: 3030303030303030
SerName: 0123456789ABCDFFFFF
hw: 3131313131313131
hwName: 0123456789ABCDFFFFF
oem: 3232323232323232
oemName: 0123456789ABCDFFFFF
JNAコール
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;
}
出力
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