“线程中的异常”;“主要”;java.lang.IllegalStateException:必须初始化数组字段

“线程中的异常”;“主要”;java.lang.IllegalStateException:必须初始化数组字段,java,arrays,jna,Java,Arrays,Jna,我需要在我的程序中使用带有结构的c++DLL。为此,我使用JNA,但当我尝试调用包含另一个struc的结构时,会发生异常 以下是结构的代码: public class SSP_PACKET extends Structure { public short packetTime; public char PacketLength; public char[] packetData; @Override protected List<String>

我需要在我的程序中使用带有结构的c++DLL。为此,我使用JNA,但当我尝试调用包含另一个struc的结构时,会发生异常

以下是结构的代码:

public class SSP_PACKET extends Structure {
    public short packetTime;
    public char PacketLength;
    public char[] packetData;

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[]{"packetTime",
                "PacketLength", 
                "packetData"});
    }    
}

public class SSP_COMMAND_INFO extends Structure {
    public byte CommandName;
    public byte LogFileName;
    public byte Encrypted;
    public SSP_PACKET Transmit = new SSP_PACKET();
    public SSP_PACKET Receive = new SSP_PACKET();
    public SSP_PACKET PreEncryptTransmit = new SSP_PACKET();
    public SSP_PACKET PreEncryptReceive = new SSP_PACKET();

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[]{"CommandName", 
                "LogFileName", 
                "Encrypted",
                "Transmit",
                "Receive",
                "PreEncryptTransmit",
                "PreEncryptReceive"});
    }
}
公共类SSP_数据包扩展结构{
公众短打包时间;
公共字符包长度;
公共字符[]packetData;
@凌驾
受保护列表getFieldOrder(){
返回Arrays.asList(新字符串[]{“packetTime”,
“包装长度”,
“packetData”});
}    
}
公共类SSP_命令_信息扩展结构{
公共字节命令名;
公共字节日志文件名;
公共字节加密;
公共SSP_数据包传输=新SSP_数据包();
公共SSP_数据包接收=新SSP_数据包();
公共SSP_数据包预加密传输=新SSP_数据包();
公共SSP_数据包预加密接收=新SSP_数据包();
@凌驾
受保护列表getFieldOrder(){
返回Arrays.asList(新字符串[]{“CommandName”,
“日志文件名”,
“加密”,
“传送”,
“接收”,
“预加密传输”,
“预加密接收”});
}
}
例外情况是:

线程“main”java.lang.IllegalStateException中的异常:数组 字段必须在以下位置初始化: com.sun.jna.Structure.deriveLayout(Structure.java:1228)位于 com.sun.jna.Structure.calculateSize(Structure.java:1097)位于 com.sun.jna.Structure.allocateMemory(Structure.java:390)位于 com.sun.jna.Structure.ensurearallocated(Structure.java:366)位于 com.sun.jna.Structure.ensurearallocated(Structure.java:356)位于 com.sun.jna.Structure.size(Structure.java:423)位于 com.sun.jna.Structure.size(Structure.java:1075)位于 com.sun.jna.Native.getNativeSize(Native.java:1271)位于 com.sun.jna.Structure.getNativeSize(Structure.java:2125)位于 com.sun.jna.Structure.getNativeSize(Structure.java:2115)位于 com.sun.jna.Structure.validateField(Structure.java:1149)位于 com.sun.jna.Structure.validateFields(Structure.java:1162)位于 Structure.java:189) Structure.java:182) Structure.java:169) Structure.java:161) SSP_COMMAND_INFO.(SSP_COMMAND_INFO.java:5)位于 test.main(test.java:10)中的验证器(Validator.java:28)


这个错误是不言自明的,它指向给您带来问题的行号。
SSP_命令\u INFO
类的第5行尝试实例化
SSP_数据包
对象,但由于尚未初始化数组,该步骤失败。JNA(以及C)不知道数组的大小,也不知道要保留多少内存

您的
public char[]packetData需要初始化为新的数组长度,例如

public char[] packetData = new char[255];
(显然,您需要咨询API以了解实际数组大小,而不是255。)

另一个重要的注意事项是,Java的
char
类型不太可能是您想要的类型。如果要将C头文件映射为
char
,则需要将其替换为
byte
。我猜你真的想要:

public byte PacketLength;
public byte[] packetData = new byte[255];

最后,无需像使用
new SSP\u PACKET()
一样初始化
SSP\u命令\u INFO
结构中的嵌套结构。JNA会自动为您执行此操作

谢谢Daniel,我是Java和JNI的初学者,所以在开发这个应用程序时遇到了一些类似的问题。你解释的方式让我成功了。