I inadvertently discovered something that doesn't make sense to me. My questions are in the code comments and below:
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
[StructLayout(LayoutKind.Sequential, Size = 4096)]
public unsafe struct BufItems
{
public fixed byte Buffer[4096];
}
public class Wrapper
{
public BufItems Items;
public int Id;
}
private unsafe void button10_Click(object sender, EventArgs e)
{
Wrapper wrap = new Wrapper();
wrap.Id = 123;
fixed(BufItems* ptr = &wrap.Items)
{
ptr->Buffer[0] = 99; // works fine
}
// fixed (Wrapper w = wrap) { /* not possible */ };
// fixed (Wrapper* w = &wrap) { /* not possible */ };
// how come I can pin the object this way?
GCHandle h = GCHandle.Alloc(wrap, GCHandleType.Pinned);
// what exactly is p pointing to? Wrapper cannot have a pointer.
IntPtr p = h.AddrOfPinnedObject();
}
One other question I have is this: I assume the field BufItems Items
is created as an object (and hence pinnable), rather than being part of the wrap
class object instantiation, right? Otherwise pinning would do nothing since wrap
could be moved by the GC. However, it's a struct, and I thought structs are "embedded" in such cases. What's actually happening here?