I have a binary file with the following contents:

The following code is used to read this contents in old VB6 program:
Private Type tpClient
Firstname As String
LastName As String
Birth As String
Adres As String
Geslacht As String
IDNummer As Long
SSNummer As String
DatabaseID As Long
Telefoon1 As String
Telefoon2 As String
End Type
Open strFilePath For Random Access Read As #intFileNumber
Get #intFileNumber, 1, ClientData ' ClientData is of type tpClient
Now I’m trying to read this with my new C# program:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PatientStruct
{
[MarshalAs(UnmanagedType.BStr)]
public string FirstName;
[MarshalAs(UnmanagedType.BStr)]
public string LastName;
[MarshalAs(UnmanagedType.BStr)]
public string BirthDate;
[MarshalAs(UnmanagedType.BStr)]
public string Address;
[MarshalAs(UnmanagedType.BStr)]
public string Gender;
[MarshalAs(UnmanagedType.BStr)]
public string IdNumber;
[MarshalAs(UnmanagedType.BStr)]
public string SsNumber;
[MarshalAs(UnmanagedType.BStr)]
public string DatabaseId;
[MarshalAs(UnmanagedType.BStr)]
public string Telephone1;
[MarshalAs(UnmanagedType.BStr)]
public string Telephone2;
}
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
T stuff = (PatientStruct)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();
However, I get an AccessViolationException on the call to Marshal.PtrToStructure.
Any suggestions?
First of all, your struct should not be a struct at all, but a class. Structs are intended for small, immutable types that represent a single value.
Making a data type marshal exactly as you want is really tricky, and as you are not doing interop you really don’t need marshalling at all. It’s easier to just use a
BinaryReaderto read the data from the file.The simple data types can be read straight off, and the strings can be read like this:
Specify an appropriate single byte encoding when opening the reader, for example windows-1252.