JNA实现C语言tInitSetting结构体是否正确?点钞机初始化失败咨询
你的JNA结构体实现存在两处核心错误,是导致初始化失败的直接原因:
- 缺失保留字段
acReserved,且字段长度定义错误
C端定义的tInitSetting结构体末尾包含长度为255字节的acReserved保留数组,你不仅注释掉了该字段,错误定义的数组长度也仅为64。JNA结构体必须和C端结构体的内存布局、大小完全匹配,少了255字节的字段会导致C端读取的结构体内存后续区域为乱值,设备自然无法识别合法的初始化参数。 - 字段顺序列表未包含所有结构体成员
即使你补全了acReserved字段,也需要将其添加到getFieldOrder返回的列表末尾,保证字段内存顺序和C端定义完全一致。
另外补充一个可选优化点:C端的unsigned int是无符号32位整型,Java的int是有符号32位整型,如果你传入的iCurrencyNum值(当前版本只需传1)不超过2^31-1,使用int不会有问题,若后续有扩展无符号大数值的需求,可以替换为JNA提供的Uint32类型。
修正后的代码示例:
import com.sun.jna.Structure; import java.util.Arrays; import java.util.List; public class TInitSetting extends Structure { // 若要严格匹配unsigned int可改为public Uint32 iCurrencyNum; public int iCurrencyNum; public byte[] acCurrencyIndex = new byte[64]; public byte cSortLevel; // 补全保留字段,长度改为255 public byte[] acReserved = new byte[255]; @Override protected List<String> getFieldOrder() { return Arrays.asList( "iCurrencyNum", "acCurrencyIndex", "cSortLevel", // 新增保留字段到顺序列表 "acReserved" ); } public static class ByReference extends TInitSetting implements Structure.ByReference {} public static class ByValue extends TInitSetting implements Structure.ByValue {} }
如果你的JNA版本在4.0以上,更推荐使用注解声明字段顺序,无需重写方法:
import com.sun.jna.Structure; @Structure.FieldOrder({"iCurrencyNum", "acCurrencyIndex", "cSortLevel", "acReserved"}) public class TInitSetting extends Structure { public int iCurrencyNum; public byte[] acCurrencyIndex = new byte[64]; public byte cSortLevel; public byte[] acReserved = new byte[255]; public static class ByReference extends TInitSetting implements Structure.ByReference {} public static class ByValue extends TInitSetting implements Structure.ByValue {} }
修改后初始化结构体时注意按文档要求给各个字段赋值即可。
内容的提问来源于stack exchange,提问作者Syed Momin Naqvi
相关产品推荐
相关产品推荐

