Announcement

Collapse
No announcement yet.

C# und Strukturen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • C# und Strukturen

    Wie kann ich folgende C_Struktur in C# definieren, somit ich einen Record mit fester Länge einlesen und auf die einzelnen Strukturelemente zugreifen kann:

    #typedef struct<BR>
    {<BR>
    char Name[20];<BR>
    char PersNr[14];<BR>
    char Strasse[50];<BR>
    int iIndex;<BR>
    } sPers;<BR>

    sPers PersRec;

    read( hHandle, &PersRec, sizeof( sPers ) );

    Danke für die Hilfe!

  • #2
    Hallo,

    ich habe nur ein Delphi-Beispiel für einen <b>packed record</b> zur Hand. Angenommen, ein "altes" Win32-Delphi-Programm hat eine strukturierte Datendatei geschrieben:
    <pre>
    <b>type</b>
    TPackedRec = <b>packed</b> <b>record</b>
    ID : Integer;
    Name : <b>String</b>[15];
    SI : Shortint;
    Kat : Byte;
    Rem : <b>String</b>[10];
    <b>end</b>;
    <br>
    <b>procedure</b> TForm1.Button1Click(Sender: TObject);
    <b>var</b>
    aRec : TPackedRec;
    f : <b>File</b> <b>Of</b> TPackedRec;
    <b>begin</b>
    aRec.ID := 1;
    aRec.Name := <font color="#9933CC">'ABCDEFGHIJKLMNO'</font>;
    aRec.SI := 2;
    aRec.Kat := 3;
    aRec.Rem := <font color="#9933CC">'1234567890'</font>;
    AssignFile(f, <font color="#9933CC">'C:\Temp\D7.dat'</font>);
    <font color="#003399"><i>{$I-}</i></font>
    Rewrite(f);
    <font color="#003399"><i>{$I+}</i></font>
    <b>Write</b>(f,aRec);
    CloseFile(f);
    <b>end</b>;
    </pre>
    Um den binären Inhalt dieser Datei einzulesen und im C#-Programm verfügbar zu machen, muss das Speicherabbildung des Delphi-Records explizit in C# deklariert werden. Dazu dient das <b>StructLayout</b>-Attribut, um bei der Hilfsstruktur die Daten aus der Datei in den Arbeitsspeicher umkopieren zu können. Um die feste Zeichenlänge bei den Strings zu berücksichtigten, wird das Attribut <b>MarshalAs(UnmanagedType.ByValArray,SizeConst=xy z)</b> genutzt, um ein char-Array der richtigen Größe anzufordern.
    <pre>
    <font color="#003399"><i>/*
    Speicherabbild der Packed Record-Struktur von Delphi für die .NET-Welt
    deklarieren (System.Runtime.InteropServices über using einbinden).
    Zusätzlich zu den String-Einträgen wird jeweils ein Hilfseintrag für die
    Stringlänge benötigt. Die Strings werden als char-Array abgelegt.
    */</i></font>
    <br>
    [StructLayout(LayoutKind.Sequential,Pack=0,CharSet= CharSet.Ansi,Size=34)]
    <b>private</b> <b>struct</b> PackedRecNative
    {
    <b>internal</b> Int32 ID;
    <b>internal</b> <b>byte</b> NameLen;
    [MarshalAs(UnmanagedType.ByValArray,SizeConst=15)]
    <b>internal</b> <b>char</b>[] Name;
    <b>internal</b> <b>sbyte</b> SI;
    <b>internal</b> <b>byte</b> Kat;
    <b>internal</b> <b>byte</b> RemLen;
    [MarshalAs(UnmanagedType.ByValArray,SizeConst=10)]
    <b>internal</b> <b>char</b>[] Rem;
    }
    <br>
    <font color="#003399"><i>/*
    Struktur für die Nutzdaten aus der Datei
    */</i></font>
    <br>
    <b>public</b> <b>struct</b> PackedRec
    {
    <b>public</b> <b>int</b> ID;
    <b>public</b> <b>string</b> Name;
    <b>public</b> <b>sbyte</b> SI;
    <b>public</b> <b>byte</b> Kat;
    <b>public</b> <b>string</b> Rem;
    }
    <br>
    <b>private</b> PackedRec ReadRecordData(System.IO.Stream s)
    {
    PackedRecNative aRawData;
    <b>int</b> iRawDataSize = Marshal.<b>SizeOf</b>(<b>typeof</b>(PackedRecNative));
    <b>byte</b>[] aData = <b>new</b> <b>byte</b>[iRawDataSize];
    s.Read(aData, 0, iRawDataSize);
    IntPtr aBuffer = Marshal.AllocHGlobal(iRawDataSize);
    <b>try</b>
    {
    Marshal.Copy(aData, 0, aBuffer, iRawDataSize);
    aRawData = (PackedRecNative)Marshal.PtrToStructure(aBuffer, <b>typeof</b>(PackedRecNative));
    }
    <b>finally</b>
    {
    Marshal.FreeHGlobal(aBuffer);
    }
    PackedRec aRec = <b>new</b> PackedRec();
    aRec.ID = aRawData.ID;
    aRec.Name = <b>new</b> <b>String</b>(aRawData.Name, 0, aRawData.NameLen);
    aRec.SI = aRawData.SI;
    aRec.Kat= aRawData.Kat;
    aRec.Rem = <b>new</b> <b>String</b>(aRawData.Rem, 0, aRawData.RemLen);
    <b>return</b> aRec;
    }
    <br>
    <b>private</b> <b>void</b> ReadFile()
    {
    System.IO.FileStream fs = <b>new</b> System.IO.FileStream(@<font color="#9933CC">&quot;c:\Temp\D7.dat&quot;</font>, System.IO.FileMode.Open);
    <b>while</b> (fs.Position &lt; fs.Length)
    {
    PackedRec r = ReadRecordData(fs);
    MessageBox.Show(r.Name, r.Rem);
    }
    }
    <br>
    <b>private</b> <b>void</b> button1_Click(<b>object</b> sender, System.EventArgs e)
    {
    ReadFile();
    }
    </pre&gt

    Comment

    Working...
    X