Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between C# marshaled struct pointers?

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. ;)

like image 208
James Wilkins Avatar asked May 20 '13 17:05

James Wilkins


People also ask

What is difference in C language?

There is a major difference between C and C++. The C language is a procedural one that provides no support for objects and classes. On the other hand, the C++ language is a combination of object-oriented and procedural programming languages.

Is C or C++ better?

Compared to C, C++ has significantly more libraries and functions to use. If you're working with complex software, C++ is a better fit because you have more libraries to rely on. Thinking practically, having knowledge of C++ is often a requirement for a variety of programming roles.

What is the relationship between C and C++?

The C language is the base language for many object-oriented programming languages like C++, a superset of C language, and Java, an extension of the C++ language. This language was originally developed to write and develop programs to build operating systems.


1 Answers

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.

like image 72
Hans Passant Avatar answered Nov 03 '22 02:11

Hans Passant