Penyelesaian Masalah C# P/Invoke Memanggil Konvensyen Konvensyen
Artikel ini menerangkan masalah biasa apabila menggunakan platform Invoke (p/invoke) untuk berinteraksi antara kod C# dan C. Kami akan memberi tumpuan kepada isu konvensyen panggilan yang tidak sesuai: dalam C# versus CallingConvention.Cdecl
dalam c. __stdcall
Konvensyen memanggil dijelaskan
Dalam persekitaran 32-bit, panggilan konvensyen menentukan parameter lulus, penyimpanan timbunan, dan pembersihan. Konvensyen utama termasuk:
__stdcall
Pemanggil menolak argumen; Callee membersihkan timbunan. Digunakan oleh Windows API dan com.
__cdecl
Pemanggil menolak argumen dan membersihkan timbunan. Standard untuk C.
__fastcall
Menggunakan daftar untuk beberapa argumen, berpotensi meningkatkan kelajuan tetapi mengurangkan keserasian.
__thiscall
Sama seperti , tetapi mengendalikan penunjuk "ini" dalam fungsi ahli C. __cdecl
__clrcall
Unsur mengimbangi konvensyen panggilan yang diuruskan dari orang lain, menghalang isu timbunan.
analisis contoh kod
Pertimbangkan fungsi C:
<code class="language-c++">extern "C" int __stdcall InvokedFunction(int);</code>
<code class="language-csharp">[DllImport("CPlusPlus.dll", ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Cdecl)] private static extern int InvokedFunction(IntPtr intArg);</code>
Clash konvensyen
Masalahnya berpunca dari dalam C# yang bertentangan dengan CallingConvention.Cdecl
dalam c. Ini membawa kepada ketidakseimbangan. Walaupun __stdcall
selalunya p/invoke lalai (kerana kelaziman API Windows), interfacing dengan kod __stdcall
C memerlukan spesifikasi konvensyen yang jelas. __cdecl
Resolusi
Penyelesaiannya adalah mudah: menyelaraskan konvensyen C# dengan C One:
<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>
Takeaway Key
Memahami konvensyen panggilan adalah penting untuk kebolehoperasian interoperabiliti silang bahasa yang berjaya. Konvensyen yang sepadan menghalang kesilapan stack dan memastikan integrasi C# dan C yang lancar.Atas ialah kandungan terperinci Mengapakah Panggilan C# P/Invoke Saya Dengan `CallingConvention.Cdecl` Gagal Apabila Memanggil Fungsi C `__stdcall`?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!