ホームページ > バックエンド開発 > C++ > C#P/CallingConvention.cdecl`を呼び出すとC#P/Invoke Callがc` __stdcall`関数を呼び出すときに失敗するのはなぜですか?

C#P/CallingConvention.cdecl`を呼び出すとC#P/Invoke Callがc` __stdcall`関数を呼び出すときに失敗するのはなぜですか?

Patricia Arquette
リリース: 2025-01-25 23:51:11
オリジナル
410 人が閲覧しました

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

C# P/呼び出し呼び出し規約の不一致のトラブルシューティング

この記事では、プラットフォーム呼び出し (P/Invoke) を使用して C# と C コードの間で対話する場合の一般的な問題について説明します。 ここでは、呼び出し規約の不一致の問題、つまり C# の CallingConvention.Cdecl と C の __stdcall に焦点を当てます。

呼び出し規約の説明

32 ビット環境では、呼び出し規約によりパラメーターの受け渡し、スタック ストレージ、クリーンアップが規定されます。主な規則には以下が含まれます:

  • __stdcall: 呼び出し元は引数をプッシュします。呼び出し先はスタックをクリーンアップします。 Windows API および COM によって使用されます。
  • __cdecl: 呼び出し元は引数をプッシュし、スタックをクリーンアップします。 C の標準
  • __fastcall: 一部の引数にレジスタを使用し、速度は向上する可能性がありますが、互換性は低下します。
  • __thiscall: __cdecl と似ていますが、C メンバー関数の "this" ポインターを処理します。
  • __clrcall: 他の要素のバランスをとるマネージド呼び出し規約で、スタックの問題を防ぎます。

コード例の分析

C 関数について考えてみましょう。

<code class="language-c++">extern "C" int __stdcall InvokedFunction(int);</code>
ログイン後にコピー

それに対応する C# P/Invoke:

<code class="language-csharp">[DllImport("CPlusPlus.dll", ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
private static extern int InvokedFunction(IntPtr intArg);</code>
ログイン後にコピー

コンベンション・クラッシュ

この問題は、C# の CallingConvention.Cdecl が C の __stdcall と競合することに起因します。これはスタックの不均衡につながります。 __stdcall は (Windows API の普及により) P/Invoke のデフォルトであることが多いですが、__cdecl C コードとのインターフェースには明示的な規約仕様が必要です。

解決策

解決策は簡単です。C# の呼び出し規約を C の呼び出し規約に合わせます。

<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>
ログイン後にコピー

重要なポイント

言語間の相互運用性を成功させるには、呼び出し規約を理解することが不可欠です。 規則を一致させることでスタック エラーが防止され、C# と C のスムーズな統合が保証されます。

以上がC#P/CallingConvention.cdecl`を呼び出すとC#P/Invoke Callがc` __stdcall`関数を呼び出すときに失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート