1

我正在开发一个 C# 应用程序,它读取二进制文件的内容并在数据网格视图中显示相同的内容。数据的格式是这样的

[StructLayout(LayoutKind.Sequential)]
public class sProtParElement
{
    public ushort wNameIndex; 
    public eDataTypeTag eDataType; //eDataTypeTag is an enum
    public ushort wLen;
    public Data_Variant_tag Vt_Var; //Data_Variant_tag is a struct
}

在哪里,

[StructLayout(LayoutKind.Explicit)]
public struct Data_Variant_tag
{
    [FieldOffset(0)]public byte yVal;
    [FieldOffset(0)]public sbyte cVal;
    [FieldOffset(0)]public ushort wVal;
    [FieldOffset(0)]public short iVal;
    [FieldOffset(0)]public uint xVal;
    [FieldOffset(0)]public int lVal;
    [FieldOffset(0)]public IntPtr pcVal;
}

现在,用户可以对数据网格视图中的数据进行更改,并将更新的数据保存在缓冲区中,以便可以再次将其写回文件。

我面临的问题是因为数据类型不同。当我想将内容写回字节数组时,由于遇到的数据类型大小不同,我无法使用固定的结构大小。

有人能告诉我如何创建一个动态缓冲区并在字节缓冲区中只写入所需的数据大小吗?

4

3 回答 3

2

您可以使用Marshal类将具有显式顺序布局的结构转换为字节数组。

var element = new sProtParElement()
{
    wLen = 1,
    wNameIndex = 2,
    Vt_Var = new Data_Variant_tag { lVal = 3 }
};

var size = Marshal.SizeOf(element);
var buffer = new byte[size];
IntPtr ptr = IntPtr.Zero;
try
{
    ptr = Marshal.AllocHGlobal(size);
    Marshal.StructureToPtr(element, ptr, true);
    Marshal.Copy(ptr, buffer, 0, size);
}
finally
{
    Marshal.FreeHGlobal(ptr);
}
于 2012-12-26T07:21:22.013 回答
0

感谢您的回复。我使用泛型与 Lambda 表达式相结合来得出我的解决方案。

由于结构中的成员根据数据类型具有不同的大小,因此我创建了一个字节数组列表,其中已经包含了数据网格视图的所有元素

现在每次,用户在数据网格视图中进行更改,我创建一个临时缓冲区并覆盖原始缓冲区内容,例如

             byte[] modifiedArray = 
             GenerateByteArrayFromPPDataList(e.RowIndex,newPPDataList[e.RowIndex].eDataType); 

      listofArrays[e.RowIndex] = modifiedArray; //listofArrays[e.RowIndex] -> byte array at index position e.RowIndex

然后我使用 lambda 表达式来向量化这个列表。我使用 stackoverflow 中的示例来执行此操作。

    /// <summary>
    /// Converst the list of byte arrays which contains the 
    /// protocol paramters into a single byte array
    /// </summary>
    private void VectorizeProtParList()
    {
        if (listofArrays != null && listofArrays.Count > 0)
        {
            var flattenedList =
                listofArrays.SelectMany(bytes => bytes);

            savedPPDataArray = flattenedList.ToArray();

            MessageBox.Show("New Protocol parameter data saved", "Save Data",
                MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        else
        {
            MessageBox.Show("PP Data list seems to have no data", "Error",
                MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

    }

savedPPDataArray 是我写回文件的最后一个字节缓冲区。

干杯,哈里什

于 2012-12-27T12:03:44.000 回答
0

您需要分配新的缓冲区。修改结构之前的所有数据必须按原样复制。修改后的缓冲区之后的所有数据都必须移位。您可以System.Buffer为此使用类。

于 2012-12-26T07:09:35.503 回答