PInvoke für C-Funktion, die char * zurückgibt
Ich bin versucht, zu schreiben, etwas C# - code, der eine Methode aufruft, die aus einer nicht verwalteten DLL. Der Prototyp für die Funktion in der dll ist:
extern "C" __declspec(dllexport) char *foo(void);
In C#, habe ich zuerst verwendet:
[DllImport(_dllLocation)]
public static extern string foo();
Es scheint zu funktionieren auf der Oberfläche, aber ich bin immer Speicher Korruption Fehler während der Laufzeit. Ich glaube, ich bin zeigt auf Speicher, der passiert, richtig zu sein, aber der bereits freigegeben wurde.
Versuchte ich mit einem PInvoke-code-gen-Dienstprogramm namens "P/Invoke Interop Assistant". Es gab mir die Ausgabe:
[System.Runtime.InteropServices.DLLImportAttribute(_dllLocation, EntryPoint = "foo")]
public static extern System.IntPtr foo();
Ist das richtig? Wenn ja, wie konvertiere ich diese IntPtr, um einen string in C#?
InformationsquelleAutor der Frage Brandon | 2008-12-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie zurück diese als IntPtr. Die Rückkehr eines Systems.String-Typ von einem PInvoke-Funktion erfordert eine große Sorgfalt. Die CLR muss die übertragung der Erinnerung von der nativen Darstellung in den verwalteten. Dies ist eine einfache und vorhersagbaren Betrieb.
Das problem aber kommt mit, was mit den nativen Speicher, der zurückgegeben wurde von foo(). Die CLR übernimmt die folgenden zwei Elemente über einen PInvoke-Funktion, die direkt liefert den string-Typ
Daher wird es Marschall der string und dann call CoTaskMemFree auf den nativen Speicher-blob. Es sei denn, Sie tatsächlich zugewiesen ist dieser Speicher mit CoTaskMemAlloc dies wird am besten für einen Absturz in der Anwendung.
Um die korrekte Semantik hier muss wieder ein IntPtr direkt. Dann verwenden Marschall.PtrToString* um einen verwalteten String-Wert. Können Sie noch brauchen, um die native Speicher aber das wird abhängig von der Implementierung von foo.
InformationsquelleAutor der Antwort JaredPar
Können Sie den Marschall.PtrToStringAuto Methode.
InformationsquelleAutor der Antwort Strelok