Die Verwendung von P/Invoke zum Aufrufen von C-Funktionen aus C# kann zu Abstürzen führen, wenn die Aufrufkonventionen nicht übereinstimmen. In diesem Artikel werden die Gründe für diese Konflikte untersucht.
Aufruf von Konventionsinkongruenzen und ihre Auswirkungen
Ein häufiges Szenario beinhaltet eine C-Funktion, die die __stdcall
-Konvention verwendet, während das entsprechende C#-DllImport
-Attribut CallingConvention.Cdecl
angibt. Dies geschieht, weil:
__stdcall
: Die Standardaufrufkonvention für Windows-APIs und viele C-Funktionen. Die aufgerufene Funktion (callee
) ist für das Aufräumen des Stapels verantwortlich. Dies ist die P/Invoke-Standardeinstellung.__cdecl
: Wird im C-Code verwendet. Die aufrufende Funktion (caller
) ist für die Stapelbereinigung verantwortlich.Das Problem: Stapelungleichgewichte
Wenn der Anrufer und der Angerufene sich über die Stapelbereinigung nicht einig sind, kommt es zu Stapelungleichgewichten. Dies führt zu Abstürzen, unvorhersehbarem Verhalten und unzuverlässigem Debuggen aufgrund verlorener Stack-Informationen.
Andere Anrufkonventionen (und warum sie wichtig sind)
__thiscall
: Wird in C für Memberfunktionen verwendet. Aufgrund der Komplexität der Vererbung und der Compilerunterschiede wird es in .NET P/Invoke nicht direkt unterstützt.__fastcall
: Verwendet CPU-Register für die Argumentübergabe. Wird im verwalteten Code nicht unterstützt.__clrcall
: Die verwaltete Codekonvention, die Aspekte von __stdcall
, __cdecl
und __fastcall
mit Laufzeitsicherheitsprüfungen kombiniert.Warum die Standard-P/Invoke-Konvention Probleme verursachen kann
Die standardmäßige P/Invoke-Aufrufkonvention (stdcall
) kollidiert häufig mit C-Code, der mit __cdecl
kompiliert wurde. Dies ist auf die historische Verbindung von __stdcall
mit Windows-APIs zurückzuführen, die zu der (falschen) Annahme führt, dass alle C-Funktionen es verwenden. Diese Nichtübereinstimmung führt zu den oben beschriebenen Problemen bei der Stapelbereinigung.
Das obige ist der detaillierte Inhalt vonWarum stürzen C# P/Invoke -Aufrufe mit `cDecl` manchmal zusammen, wenn sie mit __stdcall` c -Funktionen anpassen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!