Rückkehr Zeiger, die von nicht verwalteten auf verwaltete code
Habe ich eine nicht verwaltete dll, die Exporte die folgende Funktion:
SomeData* test();
Angenommen SomeData als:
typedef struct _Data Data;
struct _Data{
int a;
int b;
}
Nun möchte ich Sie zum aufrufen dieser Funktion aus C# - code. Ich fange an zu definieren, die der C# - Struktur benötigt, um benutzerdefinierte Marshalling wie diese:
[StructLayout(LayoutKind.Sequential)]
public class SomeData
{
public Int32 a;
public Int32 b;
}
Und jetzt erkläre ich das verwaltete Funktion:
[DllImport("DynamicLibrary.dll", CharSet=CharSet.Auto)]
[return: MarshalAs(UnmanagedType.LPStruct)]
public static extern SomeData test();
Und in der main-Funktion habe ich noch:
IntPtr ptr = test();
Dies zu tun, erhalte ich die MarchalDirectiveException: "Nicht Marschall 'return-Wert': Ungültige verwaltete/nicht verwaltete Typ-Kombination (Int/UInt muss gekoppelt werden mit SysInt oder SysUInt)."
Habe ich nicht den Speicher für SomeData in C#, da ich erwarte, dass dieser Speicher zugeordnet ist, in der C-Funktion und diese würde ich verwenden Sie die Marshal.Kopieren, um es zu übergeben, um die verwalteten Speicher.
Irgendwelche Ideen? Dank
------------------------ BEARBEITET NACH JaredPar ANTWORT --------------------
In der Tat, beging ich einen Fehler bei der Bewältigung der code auf meine Frage. Die real verwaltete Signatur war ich mit war:
[DllImport("DynamicLibrary.dll", CharSet=CharSet.Auto)]
[return: MarshalAs(UnmanagedType.LPStruct)]
public static extern IntPtr test();
Den JaredPar die Antwort noch relevant ist. Um das richtige Verhalten, habe ich 2 Möglichkeiten:
1) Verwenden Sie die 'public static extern IntPtr test();' (ohne MarshalAs-Attribut) Unterschrift und dann Zugriff auf die zurückgegebenen Zeiger wie JaredPar vorgeschlagen.
2) Verwenden Sie die 'public static extern SomeData test();' (mit dem MarshalAs-Attribut) und dann einfach mit SomeData sd = test();
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bei der Deklaration der managed-Funktion, die Sie anpassen müssen, Zeiger-Typen mit Referenzwerten oder
IntPtr
Werte. In diesem Fall ist der LPStruct modifier nicht helfen. Die einfachste Lösung ist die Umwandlung der Rückgabewert von test, um eineIntPtr
eher alsSomeData
da die native Methode ist die Rückgabe ein pointer-Wert. Sie können dann schreiben die folgenden wrapper -