首頁 > 後端開發 > C++ > 為什麼 __stdcall C 和 Cdecl C# 在 P/Invoke 中呼叫衝突,如何解決?

為什麼 __stdcall C 和 Cdecl C# 在 P/Invoke 中呼叫衝突,如何解決?

Barbara Streisand
發布: 2025-01-25 23:46:11
原創
227 人瀏覽過

Why Do __stdcall C   and Cdecl C# Calls Conflict in P/Invoke, and How Can This Be Resolved?

理解 P/Invoke 中的 Cdecl/__stdcall 衝突

P/Invoke 連接 C# 和 C,依賴匹配的呼叫約定來確保正確的參數傳遞和堆疊管理。 當使用預設(通常是 __stdcall)P/Invoke 約定從 C# 呼叫使用 cdecl 約定的 C 函數時,會出現一個常見問題。

問題的根源

不同的呼叫約定以不同的方式處理堆疊清理:

  • __stdcall:廣泛用於 Windows API 和 COM,被呼叫者(C 函數)負責清理堆疊。
  • __cdecl:預設的 C 呼叫約定,呼叫者(C# 程式碼)處理堆疊清理。
  • __thiscall:用於C成員函數;由於其複雜性,P/Invoke 不直接支援它。

不符的後果

僅將 extern "C" 加入 C 程式碼並在 C# CallingConvention.Cdecl 屬性中指定 DllImport 並不能解決問題。 不同的清理職責會導致堆疊損壞,甚至可能導致崩潰或微妙的、難以調試的錯誤,即使沒有立即發出調試器警告。 堆疊可能會被清理兩次,從而導致不可預測的行為。

解:一致的約定

關鍵是一致性。 修改 C 函數宣告以明確使用 __cdecl:將 extern "C" int __stdcall InvokedFunction(int); 替換為 extern "C" int __cdecl InvokedFunction(int);。 然後,確保您的 C# DllImport 屬性匹配:

<code class="language-csharp">[DllImport("CPlusPlus.dll", ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]</code>
登入後複製

重點

仔細注意呼叫約定對於可靠的 P/Invoke 互通性至關重要。 在 C 和 C# 之間使用一致的約定可以消除堆疊不平衡並提高程式碼的整體穩健性。

以上是為什麼 __stdcall C 和 Cdecl C# 在 P/Invoke 中呼叫衝突,如何解決?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板