Проблемы с маршалом.PtrToStructure и String - PullRequest
1 голос
/ 24 января 2011

У меня есть следующий класс

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public class xy11Dataset : SZLDataset
{
    public short Index { get; set; }

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    private string _mlfB;
    public string MlfB
    {
        get { return _mlfB; }
        set { _mlfB = value; }
    }

    public UInt16 BGTyp { get; set; }

    public UInt16 Ausbg1 { get; set; }

    public UInt16 Ausbg2 { get; set; }
}

, и я заполняю его следующим кодом:

byte[] objBuffer = new byte[retVal.Size];
Array.Copy(buffer, (n*retVal.Size) + 8, objBuffer, 0, retVal.Size);
GCHandle handle = GCHandle.Alloc(objBuffer, GCHandleType.Pinned);
datsets.Add((xy11Dataset)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(xy11Dataset)));
handle.Free();

У меня есть значения в objBuffer в позиции 2 (которая должна бытьначало строки), но строка остается пустой!

1 Ответ

3 голосов
/ 24 января 2011

Вы должны отказаться от использования авто свойств здесь. Они генерируют частное вспомогательное поле, которое не последовательно со свойством, оно добавляется в конец. Вы можете увидеть их с помощью ildasm.exe, они имеют имя, например <Index>k_Backingfield. Вам нужно, чтобы это выражение возвращало правильное значение:

        int offs = (int)Marshal.OffsetOf(typeof(xy11Dataset), "_mlfB");

Я не вижу, что содержит SZLDataSet, но без него это возвращает 0 прямо сейчас. Не правильно, вам нужно 2. Лучше всего объявить структуру с открытыми полями, расположение которых точно совпадает с данными в буфере. Инициализируйте объект класса из значения.

...