我对JNA很新。我有一个问题,即我将一个Structure传递给一个更新一些变量的库调用。当我从主方法直接在C代码中执行它时,它可以工作,但是当我尝试使用JNA访问它时,值不会更新。
我想要获取的值是:ser,serName,hw,hwName,oem,oemName
我试图在JNA中访问的方法:
__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;
}
这个方法的JNA声明是
public boolean GetSN(DevProgramInfo devInfo, byte sessionID);
我在Java中构建了结构,这里是在java中创建的“sn.sn”
public class mySN extends Union {
/// C type : field_struct
public field_struct field;
/// C type : sn_struct
public sn_struct sn;
/// <i>native declaration : line 3</i>
/// <i>native declaration : line 3</i>
public static class field_struct extends Structure {
/// unique to each pid+version+variant
public NativeLong sequence;
public byte variant;
public byte version;
public short pid;
public field_struct() {
super();
}
protected List getFieldOrder() {
return Arrays.asList("sequence", "variant", "version", "pid");
}
public field_struct(NativeLong sequence, byte variant, byte version, short pid) {
super();
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 boolean copy(field_struct fieldInfo) {
this.sequence = fieldInfo.sequence;
this.variant = fieldInfo.variant;
this.version = fieldInfo.version;
this.pid = fieldInfo.pid;
return true;
}
};
/// <i>native declaration : line 9</i>
/// <i>native declaration : line 9</i>
public static class sn_struct extends Structure {
public NativeLong ser;
public byte[] serName = new byte[20];
public NativeLong hw;
public byte[] hwName = new byte[20];
public NativeLong oem;
public byte[] oemName = new byte[20];
public sn_struct() {
super();
}
protected List getFieldOrder() {
return Arrays.asList("ser", "serName", "hw", "hwName", "oem", "oemName");
}
public sn_struct(NativeLong ser, byte serName[], NativeLong hw, byte hwName[], NativeLong oem, byte oemName[]) {
super();
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 mySN() {
super();
}
/// @param sn C type : sn_struct
public mySN(sn_struct sn) {
super();
this.sn = sn;
setType(sn_struct.class);
}
/// @param field C type : field_struct
public mySN(field_struct field) {
super();
this.field = field;
setType(field_struct.class);
}
public static class ByReference extends mySN implements Structure.ByReference {
};
public static class ByValue extends mySN implements Structure.ByValue {
};
}
当我使用代码时
myJNA.getSN(devInfo, (byte) 0);
所有变量(ser,serName,hw,hwName,oem,oemName)都是0。我已经被困在这个问题上大约一个星期了,我似乎无法弄清楚这个问题。
当我将printf添加到DLL时,会在那里的结构中生成正确的值,但是我没有在Java中的对象中获取这些值。
任何帮助将不胜感激!
答案 0 :(得分:1)
您正在使用Union
。除非你设置“active”类型,否则JNA只能自动读回原始字段(你不希望它回读一个union的'const char *`字段,如果它实际上只是一个值为零的整数)。 / p>
如果您知道,请在通话前拨打Union.setType(Class)
;否则在本地呼叫之后调用它,然后Structure.read()
。