Why can't I use Marshal.Copy () to update the structure?

I have code designed to get a structure from an array of bytes:

    public static T GetValue<T>(byte[] data, int start) where T : struct
    {
        T d = default(T);
        int elementsize = Marshal.SizeOf(typeof(T));

        GCHandle sh = GCHandle.Alloc(d, GCHandleType.Pinned);
        Marshal.Copy(data, start, sh.AddrOfPinnedObject(), elementsize);
        sh.Free();

        return d;
    }

However, the structure dnever changes and always returns the default value.

I was looking for the “right” way to do this, and use it instead, but I'm still interested because I don’t understand why this should not work.

Its as simple as it can be: allocate some memory, d, get a pointer to it, copy some bytes to the memory indicated by this, return. Not only that, but when I use similar code, but with d - an array from T, it works fine. If sh.AddrOfPinnedObject () doesn't really point to d, but then what is its point?

- , ?

+5
3

, .Net.

structs (*), . , , . , , .

AddrOfPinnedObject - , , struct.

, .

(*) :

1  2
 3 " "
 4

(nb 3 4 1)

+4
    GCHandle sh = GCHandle.Alloc(d, GCHandleType.Pinned);

, . - , GCHandle.Alloc() . , . , . # , , . , System.Object. Quacks-like-a-duck typing.

, Marshal.Copy() . . , .

Marshal.PtrToStructure(). smarts ( StructLayout) . , .

+8

Here is a working example:

public static T GetValue<T>(byte[] data, int start) where T : struct
{
    int elementsize = Marshal.SizeOf(typeof(T));

    IntPtr ptr = IntPtr.Zero;

    try
    {
        ptr = Marshal.AllocHGlobal(elementsize);

        Marshal.Copy(data, start, ptr, elementsize);
        return (T)Marshal.PtrToStructure(ptr, typeof(T));
    }
    finally
    {
        if (ptr != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(ptr);
        }
    }
}

But I would use an explicit layout here due to the alignment of the structure .

[StructLayout(LayoutKind.Explicit, Size = 3)]
public struct TestStruct
{
    [FieldOffset(0)]
    public byte z;

    [FieldOffset(1)]
    public short y;
}
+1
source

All Articles