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クラスを使用して、 ExplicitおよびSequentialレイアウトの構造をバイト配列に変換できます。

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

次に、ラムダ式を使用してこのリストをベクトル化します。これを行うために、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 に答える