Angenommen, ich habe eine Struktur:
%Vor%und eine C ++ Funktion:
%Vor%Zuerst - meine IDE. Ich verwende Visual Studio 2010 und erstelle eine C # (4.0) -Anwendung. Der C ++ Teil ist auch in VS2010 eingebaut.
Ich weiß, wie man eine DLL von C / C ++ - Code erstellt und sie in C # -Anwendungen verwendet, aber bis heute habe ich nur primitive Argumente verwendet und gebe Werte zurück wie:
%Vor%Heute muss ich ein Array von structs übergeben (wie im obigen Beispiel) .. und vielleicht auch eins zurück ..
Wie kann ich eine C # -Klasse in eine C-Struktur "übersetzen" (und umgekehrt) ??
Die Struktur kann wie folgt deklariert werden:
%Vor% Als nächstes müssen Sie auf einer Aufrufkonvention beruhigen. Ihr C ++ Code wird fast sicher mit cdecl
kompiliert. Bleiben wir dabei.
Die erste Funktion ist einfach von C # aus aufzurufen:
%Vor% Beachten Sie, dass Sie SetLastError
nicht hier verwenden sollten - das ist für Windows-API-Funktionen. Und es ist nicht nötig, CharSet
zu setzen, da hier kein Text vorhanden ist.
Nun, für another
werden die Dinge komplexer. Wenn Sie den Speicher im C # -Code reservieren können, dann ist das definitiv der Weg zu gehen.
Auf der C # -Seite deklarieren Sie es wie folgt:
%Vor%und nenne es so
%Vor%Wenn Sie nicht auf der C # -Seite des Zauns reservieren möchten, dann tun Sie das wie folgt:
CoTaskMemAlloc
. IntPtr
. Marshal.PtrToStructure
und einige Zeigerarithmetik, um das Rückgabearray in ein C # -Array zu marshalieren. Marshal.FreeCoTaskMem
auf, um den im nativen Modul zugewiesenen Speicher freizugeben. Aber wenn Sie meinen Rat brauchen, versuchen Sie, das Array im verwalteten Code zuzuordnen.
Es sollte so einfach sein:
%Vor% Die Probleme, auf die Sie möglicherweise stoßen, wären, wenn in der C-Version der Struktur und möglicherweise im Strukturlayout ein Packen ausgeführt wird. Wenn das Layout nicht übereinstimmt, möchten Sie es möglicherweise in LayoutKind.Explicit
ändern und das Attribut [FieldOffset(0)]
für jedes Feld verwenden. C hätte auch keine Ahnung, die Länge des Vertices-Arrays wurde überschritten. Wenn sich das ändert, möchten Sie das an die Methode weiterleiten.
Um ein Array zurück zu bekommen:
%Vor% Der Marshaler behandelt alle Speicherprobleme beim Übergeben von Argumenten in, aber beim Zurückgeben des Arrays kann er nichts tun. Da der Speicher auf dem nicht verwalteten Heap zugeordnet ist, hat der GC keine Ahnung davon, und Sie werden mit einem Speicherverlust enden. Der Marshaller kopiert einfach die systemeigenen Strukturen in das Array der verwalteten Struktur, kann jedoch den Speicher, den Sie zugewiesen haben, nicht mit malloc
freigeben.
Der einfachste Weg, um es zu umgehen, wenn Sie den C ++ - Code ändern können, wäre, die Signatur von another
zu ändern, um ein Array von Vertices (und die Länge des Arrays) aufzunehmen, anstatt eins zurückzugeben. Ich muss keinen Code für dich schreiben, der das tut, @DavidHeffernan hat dies bereits in seiner Antwort getan, dem Teil der Pause.