Heim >Backend-Entwicklung >C++ >Warum schlägt mein C#-P/Invoke-Aufruf mit „CallingConvention.Cdecl' fehl, wenn eine C-Funktion „__stdcall' aufgerufen wird?

Warum schlägt mein C#-P/Invoke-Aufruf mit „CallingConvention.Cdecl' fehl, wenn eine C-Funktion „__stdcall' aufgerufen wird?

Patricia Arquette
Patricia ArquetteOriginal
2025-01-25 23:51:11452Durchsuche

Why Does My C# P/Invoke Call With `CallingConvention.Cdecl` Fail When Calling a C   `__stdcall` Function?

Fehlerbehebung bei Nichtübereinstimmungen der C# P/Invoke Calling Convention

In diesem Artikel wird ein häufiges Problem bei der Verwendung von Platform Invoke (P/Invoke) zur Interaktion zwischen C#- und C-Code erläutert. Wir konzentrieren uns auf das Problem nicht übereinstimmender Aufrufkonventionen: CallingConvention.Cdecl in C# versus __stdcall in C.

Anrufkonventionen erklärt

In 32-Bit-Umgebungen bestimmen Aufrufkonventionen die Parameterübergabe, Stapelspeicherung und Bereinigung. Zu den wichtigsten Konventionen gehören:

  • __stdcall: Der Anrufer bringt Argumente vor; Der Angerufene bereinigt den Stapel. Wird von Windows-APIs und COM verwendet.
  • __cdecl: Der Aufrufer schiebt Argumente und bereinigt den Stapel. Standard für C.
  • __fastcall: Verwendet Register für einige Argumente, was möglicherweise die Geschwindigkeit verbessert, aber die Kompatibilität verringert.
  • __thiscall: Ähnlich wie __cdecl, verarbeitet aber den „this“-Zeiger in C-Memberfunktionen.
  • __clrcall: Eine verwaltete Aufrufkonvention, die Elemente von anderen ausgleicht und Stapelprobleme verhindert.

Code-Beispielanalyse

Stellen Sie sich eine C-Funktion vor:

<code class="language-c++">extern "C" int __stdcall InvokedFunction(int);</code>

Und sein C# P/Invoke-Gegenstück:

<code class="language-csharp">[DllImport("CPlusPlus.dll", ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
private static extern int InvokedFunction(IntPtr intArg);</code>

The Convention Clash

Das Problem ergibt sich daraus, dass CallingConvention.Cdecl in C# mit dem __stdcall in C in Konflikt steht. Dies führt zu Stapelungleichgewichten. Während __stdcall häufig der P/Invoke-Standardwert ist (aufgrund seiner Windows-API-Prävalenz), erfordert die Schnittstelle mit __cdecl C-Code eine explizite Konventionsspezifikation.

Auflösung

Die Lösung ist einfach: Richten Sie die C#-Aufrufkonvention an der C-Konvention aus:

<code class="language-csharp">[DllImport("CPlusPlus.dll", ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Stdcall)]
private static extern int InvokedFunction(int intArg); // Note: IntPtr changed to int</code>

Schlüssel zum Mitnehmen

Das Verständnis von Aufrufkonventionen ist für eine erfolgreiche sprachübergreifende Interoperabilität von entscheidender Bedeutung. Passende Konventionen verhindern Stapelfehler und sorgen für eine reibungslose C#- und C-Integration.

Das obige ist der detaillierte Inhalt vonWarum schlägt mein C#-P/Invoke-Aufruf mit „CallingConvention.Cdecl' fehl, wenn eine C-Funktion „__stdcall' aufgerufen wird?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn