开发者

Read variable sized string from binary file (VB6 vs. C#)

开发者 https://www.devze.com 2023-01-30 21:22 出处:网络
I have a binary file with the following contents: The following code is used to read this contents in old VB6 program:

I have a binary file with the following contents:

Read variable sized string from binary file (VB6 vs. C#)

The following code is used to read this contents in old VB6 program:

Private Type tpClient
    Firstname As String
    LastName As String
    Bir开发者_运维百科th 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?


Marshal.PtrToStructure is expecting the buffer to be full of pointers to strings. I don't think Marshal can be used to do what you want.

Instead, you'll need to determine the binary file format and write the code for this by hand. Take a look at the BinaryReader class.

Edit: If you're stuck, you could add a reference to Microsoft.VisualBasic.dll and use the FileSystem.FileGetObject method. This behaves the same as the Get keyword in VB6.


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 BinaryReader to read the data from the file.

The simple data types can be read straight off, and the strings can be read like this:

string value = reader.ReadChars(reader.ReadShort());

Specify an appropriate single byte encoding when opening the reader, for example windows-1252.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号