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
Freigeben: 2025-01-25 23:51:11
Original
410 Leute haben es durchsucht

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>
Nach dem Login kopieren

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>
Nach dem Login kopieren

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>
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage