C# P/呼び出し呼び出し規約の競合について: Cdecl と Stdcall の比較
プラットフォーム呼び出し (P/Invoke) は、マネージド (C#) コードとアンマネージド (C など) コードをブリッジします。 ただし、呼び出し規約の不一致により、相互運用性の問題が発生する可能性があります。
問題の原因
この競合は、C と C# のデフォルトの P/Invoke 設定の間の呼び出し規約の処理の違いに起因します。
__stdcall
規則が使用されます。 呼び出された関数 (callee
) はスタックのクリーンアップを担当します。CallingConvention.Winapi
であり、Windows では __stdcall
に相当します。主な呼び出し規約の違い:
主な違いは次のとおりです。
__stdcall
と C# の CallingConvention.Winapi
(または CallingConvention.Stdcall
)。__cdecl
(C でよく使用されます) は、スタックをクリーンアップするために呼び出し関数 (caller
) を必要とします。 __stdcall
はこれを callee
に割り当てます。間違った P/Invoke 宣言の例:
C 関数が CallingConvention.Cdecl
を使用するときに、間違った C# 宣言により __stdcall
が使用される可能性があります。これにより、スタックの破損や実行時エラーが発生します。
正しい C# 宣言:
互換性を確保するには、C# の DllImport
属性が C 関数の規則と一致する必要があります。
<code class="language-csharp">[DllImport("CPlusPlus.dll", ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Winapi)] private static extern int InvokedFunction(IntPtr intArg);</code>
規約の不一致の防止:
アンマネージ関数の呼び出し規約を常に確認し、それを C# の DllImport
宣言に正確に反映してください。 サポートされている呼び出し規約の詳細については、Microsoft のドキュメントを参照してください。
以上がC#P/InvokeでCDECLとSTDCALLの呼び出しコンベンションの不一致が不一致になるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。