Я собираюсь сохранить файл DataTable
в * .dbf (dBase IV). Таким образом, у меня есть структура вроде этого:`Marshal.StructureToPtr` выдает исключение, пытаясь получить представление массива байтов структуры
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct DbfHeader
{
[FieldOffset(0)]
private byte versionNumber;
[FieldOffset(1)]
private byte yearOfLastUpdate;
[FieldOffset(2)]
private byte monthOfLastUpdate;
[FieldOffset(3)]
private byte dayOfLastUpdate;
[FieldOffset(4)]
private Int32 numberOfRecords;
[FieldOffset(8)]
private Int16 lengthOfHeader;
[FieldOffset(10)]
private Int16 lengthOfEachRecord;
[FieldOffset(12)]
private Int16 reserved1;
[FieldOffset(14)]
private byte incompleteTransaction;
[FieldOffset(15)]
private byte encryptionFlag;
[FieldOffset(16)]
private byte[] freeRecordThread;
[FieldOffset(20)]
private byte[] reserved2;
[FieldOffset(28)]
private byte mdxFlag;
[FieldOffset(29)]
private byte languageDriver;
[FieldOffset(30)]
private Int16 reserved3;
public DbfHeader(int numberOfRecords, int numberOfFields, short recordLength, Encoding encoding)
{
// some code that initialize each field
}
}
Кроме того, у меня есть метод, чтобы преобразовать DbfHeader
переменные byte[]
массив как это:
public static byte[] StructureToByteArray<T>(T structure)
{
int len = Marshal.SizeOf(structure);
byte[] result = new byte[len];
IntPtr ptr = Marshal.AllocHGlobal(len);
Marshal.StructureToPtr(structure, ptr, true);
Marshal.Copy(ptr, result, 0, len);
Marshal.FreeHGlobal(ptr);
return result;
}
Но этот метод не работает. На Marshal.StructureToPtr(structure, ptr, true)
линии, я получаю это исключение:
Attempted to read or write protected memory.
This is often an indication that other memory is corrupt.
Любой знает, что происходит не так? Любая помощь будет оценена.
Хотя это стандартная практика в C, в C# редко можно копировать между массивами байтов и структурами. Маршаллинг предназначен для вызова неуправляемого кода, который вы здесь не делаете. Посмотрите на [класс BinaryWriter] (http://msdn.microsoft.com/en-us/library/system.io.binarywriter.aspx). – dtb
@dtb Да. Это верно. Но чтение/запись всех этих полей с классами BinaryReader/BinaryWriter выглядит жестко. Когда вам нужно сделать это для нескольких структур, это будет сложнее. Поэтому я думал, что написать одну функцию может решить ее для всех структур, которые у меня есть. –
@dtb Есть ли другой способ сопоставления байтовых массивов и структур (в C#) с использованием одной функции? –