我用Javolution实现了以下实现:
public class RunScan extends Struct
{
public final Signed32 numOfClusters = new Signed32();
public final ClusterData[] clusters;
public final Signed32 numOfRecons = new Signed32();
public final ReconData[] recons ;
public RunScan (int numOfClusters, int numOfRecons)
{
this.numOfClusters.set(numOfClusters);
this.numOfRecons.set(numOfRecons);
clusters = array(new ClusterData[numOfClusters]);
recons = array(new ReconData[numOfRecons]);
}
}
public class ClusterData extends Struct
{
public final UTF8String scanType = new UTF8String(CommInterfaceFieldConstants.SCAN_TYPE_SIZE);
public final UTF8String patientId = new UTF8String(CommInterfaceFieldConstants.PATIENT_ID_SIZE);
.
.
.
}
public class ReconData extends Struct
{
public final UTF8String patientId = new UTF8String(CommInterfaceFieldConstants.PATIENT_ID_SIZE);
public final UTF8String scanSeriesId = new UTF8String(CommInterfaceFieldConstants.SCAN_SERIES_ID_SIZE);
.
.
.
}
在我们的通信类中,在将数据放入套接字之前,我们需要获取RunScan对象的bytes [],但在带有“ // <<<<<<<
private byte[] getCmdBytes(Struct scCmd)
{
ByteBuffer cmdBuffer = scCmd.getByteBuffer();
int cmdSize = scCmd.size();
byte[] cmdBytes = new byte[cmdSize];
if (cmdBuffer.hasArray())
{
int offset = cmdBuffer.arrayOffset() + scCmd.getByteBufferPosition();
System.arraycopy(cmdBuffer.array(), offset, cmdBytes, 0, cmdSize);
}
else
{
String msg = "\n\ncmdBufferRemaining=" + cmdBuffer.remaining() + ", cmdBytesSize=" + cmdBytes.length + "\n\n";
System.out.println(msg);
cmdBuffer.position(scCmd.getByteBufferPosition());
cmdBuffer.get(cmdBytes); //<<<<<<<<<< underFlowException
}
return cmdBytes;
}
此方法在其他情况下也有效。发生这种情况是因为这一行,
ByteBuffer cmdBuffer = scCmd.getByteBuffer();
我认为,它仅返回RunScan对象的8个字节(来自其余方法)ByteBuffer,这是这两个Signed32字段。但是这条线
int cmdSize = scCmd.size();
返回RunScan对象的正确长度,该长度包括这两个数组的大小。
如果我在用硬编码长度声明它们(而不是在构造函数中“新”创建)这两个数组时创建它们,那么它将正常工作而没有任何异常。
任何人都可以帮助我弄清楚我们的实现有什么问题吗?
最佳答案
我的代码遇到了类似情况。通常,对于当前的Struct对象,不能在与包含数组中元素数量的成员相同的结构中定义可变长度数组。
尝试这样的事情:
public class RunScanHeader extends Struct
{
public final Signed32 numOfClusters = new Signed32();
public final Signed32 numOfRecons = new Signed32();
}
public class RunScanBody extends Struct
{
public final ClusterData[] clusters;
public final ReconData[] recons ;
public RunScan (int numOfClusters, int numOfRecons)
{
clusters = array(new ClusterData[numOfClusters]);
recons = array(new ReconData[numOfRecons]);
}
}
然后,您将需要一种两阶段的方法来进行读取和写入,首先读取/写入标头数据,然后读取/写入主体数据。
抱歉,我目前没有更多详细信息,如果您不能解决此问题,请告诉我,我将深入研究我的代码。