2012-12-26 3 views
1

이진 파일의 내용을 읽고 DataGrid 뷰에 표시하는 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; 
} 

의 데이터 그리드보기에서 데이터를 변경하고 버퍼에 업데이트 된 데이터를 저장할 수있는 사용자 있도록 파일에 다시 기록 할 수 있습니다.

내가 직면 한 문제는 다양한 데이터 유형 때문입니다. 내용을 바이트 배열에 다시 쓰고 싶을 때, 내가 만나는 다양한 데이터 유형 크기 때문에 고정 된 구조체 크기를 사용할 수 없다.

동적 버퍼를 만들고 바이트 버퍼에 필요한 데이터 크기 만 쓰는 방법을 말해 줄 수 있습니까?

답변

0

새 버퍼를 할당해야합니다. 수정 된 구조 이전의 모든 데이터는 그대로 복사해야합니다. 수정 된 버퍼 이후의 모든 데이터는 이동해야합니다. 이 경우 System.Buffer 클래스를 사용할 수 있습니다.

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); 
} 
0

답장을 보내 주셔서 감사합니다. 내 솔루션에 도달하기 위해 람다 식과 결합 된 제네릭을 사용했다. 구조의 멤버는 데이터 유형에 따라 서로 다른 크기의 때문에

가 이미 지금마다 데이터 그리드보기

의 모든 요소를 ​​보유 바이트 배열의 목록을 작성, 사용자가 변경하는 데이터 그리드보기에서 임시 버퍼를 만들고 원래의 버퍼 내용을 덮어 씁니다.

   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는 파일에 다시 쓰는 최종 바이트 버퍼입니다.

건배, 하리 쉬