2013-05-20 3 views
6

Ok, das funktioniert:Was ist der Unterschied zwischen C# Marshalled Struct Pointern?

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

... und dies nicht ...

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

Also, was ist der Unterschied? Ich vermisse etwas. Ein Aufruf von "DisposeValueProxy()" gibt den folgenden Fehler:

"Kann 'Parameter # 1' nicht marshalieren: Zeiger können nicht auf Marshalling-Strukturen verweisen. Verwenden Sie ByRef statt.“

(und ja, ich kann einfach IntPtr/void * statt verwenden "ValueProxy *", aber das ist nicht mein Punkt).

Ein Aufruf von "DisposeHandleProxy()" funktioniert gut.

Mal sehen, ob jemand diese eine herausfinden können;..)

+0

Wie definieren Sie "nicht funktioniert"? –

+0

Habe gerade den Post aktualisiert, danke. –

+0

Für das Leben von mir kann ich nicht verstehen, warum Sie explizites Layout hier verwenden. Ich sehe auch keine Notwendigkeit für "unsicher". –

Antwort

8

eine Struktur blitfähig sein muss, einen Zeiger darauf erstellen die zweite Struktur nicht blitfähig ist, das Bool Feld ist der Querulant Sie. würde es stattdessen ein Byte oder int machen, abhängig von der Absicht

Eine Übersicht über die Arten, die in .NET blitable sind, ist available here.

Der Ratschlag der Ausnahmebedingungsnachricht ist sehr stichhaltig, deklarieren Sie das Argument stattdessen als ref ValueProxy, um es dem Pinvoke-Marshaller zu überlassen, eine Kopie der Struktur mit dem gewünschten Layout zu erstellen.

+0

Sie Sir sind großartig, danke. ;) Ich dachte Bool wäre eine "sichere Sache" (weil ich bereits Probleme mit nicht-blitable Typen kannte), aber ich hatte nicht bemerkt, dass Bool nicht einer von ihnen war. Ich denke, das ist eine wirklich dumme Situation, aber ich denke, da es nativ 8-Bit- oder 32-Bit-Bools geben kann (abhängig vom Compiler), ist es vielleicht ein bisschen sinnvoll. ;) Es ist schade, wie immer, MS macht es schwer herauszufinden, was mit diesen nutzlosen Fehlermeldungen los ist. Es sollte etwas wie "Struktur ist nicht blitable" gewesen sein. ;) –