Heim >Backend-Entwicklung >C++ >Wie vermeide ich System.AccessViolationException beim Übergeben von Zeichenfolgen zwischen C# und einer C-DLL?
Übergabe von Strings zwischen C# und C-DLL: Ein Minimalbeispiel
Problemstellung
Trotz Nach einem scheinbar einfachen Ansatz führt die Übergabe von Zeichenfolgen zwischen C# und einer C-DLL über Interop zu einer System.AccessViolationException. Der Code in beiden Sprachen scheint korrekt zu sein, was zu Verwirrung hinsichtlich der Grundursache des Problems führt.
C-Code
Der C-Code definiert eine Funktion, concat, die verkettet zwei Zeichenfolgen und gibt das Ergebnis zurück. Diese Funktion ist für den Export in die DLL mit __declspec(dllexport) markiert.
extern "C" { string concat(string a, string b){ return a + b; } }
C#-Code
In C# importiert der Code die Concat-Funktion mit DllImport. Die CallingConvention wird auf Cdecl gesetzt, um der C-Konvention zu entsprechen.
[DllImport("*****.dll", CallingConvention = CallingConvention.Cdecl)] static extern string concat(string a, string b);
Ausnahme und Analyse
Der Aufruf von concat("a", "b") in C# löst Auslösungen aus eine System.AccessViolationException. Diese Ausnahme weist darauf hin, dass innerhalb des nativen Codes ein ungültiger Speicherzugriff auftritt.
Lösung: Interop-kompatible Typen
Der Schuldige des Problems liegt in der Verwendung von C std ::string über die Interop-Grenze hinweg. C# kann std::string-Objekte nicht direkt erstellen oder verarbeiten. Stattdessen müssen interopkompatible Typen für den Datenaustausch verwendet werden.
Interopfreundliche Datentypen
Geeignete Interoptypen umfassen nullterminierte Arrays von Zeichen für die Übergabe von Zeichenfolgen C# zu C . Bei der Übergabe von Strings von C an C# kann ein StringBuilder verwendet werden, wobei der Aufrufer den Puffer zuweist und der Aufgerufene hineinschreibt.
Geänderter Code
In C , Die Concat-Funktion kann mit den Parametern char* und int deklariert werden, um einen Puffer und seine Länge zu erhalten.
extern "C" { void concat(char *str, int len) { // Concatenate strings and write to buffer } }
In C#, der StringBuilder kann genutzt werden.
[DllImport("...", CallingConvention = CallingConvention.Cdecl)] static extern void concat(StringBuilder str, int len); .... StringBuilder sb = new StringBuilder(10); concat(sb, sb.Capacity);
Durch die Verwendung interopkompatibler String-Typen kann der Austausch von Strings zwischen C# und der C-DLL effektiv erleichtert werden.
Das obige ist der detaillierte Inhalt vonWie vermeide ich System.AccessViolationException beim Übergeben von Zeichenfolgen zwischen C# und einer C-DLL?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!