Wie kann ich Sie richtig zurückgeben eines char * von einer nicht verwalteten DLL in C#?
Funktion Signatur:
char * errMessage(int err);
Mein code:
[DllImport("api.dll")] internal static extern char[] errMessage(int err); ... char[] message = errMessage(err);
Dieser gibt einen Fehler zurück:
Nicht der Marschall 'return-Wert': Ungültige verwaltete/nicht verwaltete Typ-Kombination.
Was mache ich falsch? Vielen Dank für jede Hilfe.
Du musst angemeldet sein, um einen Kommentar abzugeben.
versuchen Sie dies:
Ich glaube, dass C# ist smart genug, um die Zeiger und kehren Sie ein string.
Edit: Hinzugefügt, das MarshalAs-Attribut
CoTaskMemFree
. Es sei denn, der string zugewiesen wurde, durch den AufrufCoTaskMemAlloc
dies ist in der Regel ein Leck oder ein runtime error, oder beides.Eine einfache und robuste Möglichkeit ist das reservieren eines Puffers in C# in der form-wenn eine
StringBuilder
werden, übergeben Sie es an den nicht verwalteten code und füllen Sie es dort.Beispiel:
C
C#
Test:
Sehen diese Frage. Die Zusammenfassung, die Funktion zurückgeben sollte einen IntPtr und verwenden Sie die Marshal.PtrToString* konvertieren Sie es in einen verwalteten String-Objekt.
Es ist eine schreckliche Funktion, Unterschrift, es gibt keine Möglichkeit, zu erraten, wie der string zugewiesen wurde. Noch können Sie freigeben der Speicher für den string. Wenn Sie deklarieren, die den Rückgabetyp "string" in der Erklärung dann den P/Invoke-marshaller wird call CoTaskMemFree() auf die Zeiger. Das ist sehr unwahrscheinlich, angemessen zu sein. Es wird, treten Fehler in XP, aber zum Absturz Ihres Programms in Vista und Win7.
Kann man noch nicht zuverlässig rufen Sie die Funktion in einer nicht verwalteten Programm. Die Chancen, dass Sie möchten, verwenden Sie die richtige version von free() sind ziemlich schlank. Alles, was Sie tun können, ist zu deklarieren, es als IntPtr und Marschall der Rückgabewert sich mit dem Marschall.PtrToStringAnsi(). Sicher sein, ein Testprogramm zu schreiben, dass bedeutet also eine million mal, während Sie beobachten es in Taskmgr.exe. Wenn die VM-Größe für das Programm wächst ohne Grenze, haben Sie ein Speicherleck kann man nicht stecken.
Versuchen Sie es mit String in der verwalteten Seite. Sie könnte genauso gut setzen Sie den Zeichensatz auf Ansi