Reputation: 7367
Ok, this is working:
[StructLayout(LayoutKind.Explicit, Size = 28)]
public unsafe struct HandleProxy
{
[FieldOffset(0), MarshalAs(UnmanagedType.I4)]
public JSValueType _ValueType; // JSValueType is an enum
[FieldOffset(4), MarshalAs(UnmanagedType.I4)]
public Int32 _ManagedObjectID;
[FieldOffset(8)]
public void* _NativeEngineProxy;
[FieldOffset(16), MarshalAs(UnmanagedType.I4)]
public Int32 _EngineID;
[FieldOffset(20)]
public void* _Handle;
}
[DllImport("Proxy")]
public static extern void DisposeHandleProxy(HandleProxy* handle);
... and this does not ...
[StructLayout(LayoutKind.Explicit, Size = 20)]
public unsafe struct ValueProxy
{
[FieldOffset(0), MarshalAs(UnmanagedType.I4)]
public JSValueType _ValueType; // 32-bit type value.
[FieldOffset(4), MarshalAs(UnmanagedType.Bool)]
public bool _Boolean;
[FieldOffset(4), MarshalAs(UnmanagedType.I4)]
public Int32 _Integer;
[FieldOffset(4)]
public double _Number;
[FieldOffset(12)]
public void* _String;
}
[DllImport("Proxy")]
public static extern void DisposeValueProxy(ValueProxy* valueProxy);
So, what's the difference? I'm missing something. A call to "DisposeValueProxy() gives the following error:
"Cannot marshal 'parameter #1': Pointers cannot reference marshaled structures. Use ByRef instead."
(and yes, I can simply use IntPtr/void* instead of "ValueProxy*" but that's not my point).
A call to "DisposeHandleProxy()" works fine.
Let's see if someone can figure this one out. ;)
Upvotes: 7
Views: 1497
Reputation: 941545
A struct must be blittable to create a pointer to it. The second struct is not blittable, the bool field is the troublemaker. You'd have to make it a byte or int instead, depending on the intention.
An overview of what types are blittable in .NET is available here.
The exception message's advice is a very sound one, declare the argument as ref ValueProxy
instead to leave it up to the pinvoke marshaller to create a copy of the struct with the desired layout.
Upvotes: 9