Memahami Cdecl/__stdcall Konflik dalam P/Invoke
P/Invoke, merapatkan C# dan C , bergantung pada padanan konvensyen panggilan untuk memastikan hantaran hujah dan pengurusan tindanan yang betul. Masalah biasa timbul apabila fungsi C menggunakan konvensyen __stdcall
dipanggil daripada C# menggunakan konvensyen P/Invoke lalai (selalunya cdecl
).
Punca Masalah
Konvensyen panggilan yang berbeza mengendalikan pembersihan tindanan secara berbeza:
__stdcall
: Digunakan secara meluas dalam Windows API dan COM, pemanggil (fungsi C) bertanggungjawab untuk membersihkan tindanan.__cdecl
: Konvensyen panggilan C lalai, di mana pemanggil (kod C#) mengendalikan pembersihan tindanan.__thiscall
: Digunakan untuk fungsi ahli C; ia tidak disokong secara langsung dalam P/Invoke kerana kerumitannya.Akibat Ketidakpadanan
Hanya menambah extern "C"
pada kod C dan menyatakan CallingConvention.Cdecl
dalam atribut C# DllImport
tidak akan menyelesaikan masalah. Tanggungjawab pembersihan yang berbeza membawa kepada rasuah tindanan, yang berpotensi menyebabkan ranap atau ralat halus yang sukar dinyahpepijat, walaupun tanpa amaran penyahpepijat segera. Tindanan mungkin dibersihkan dua kali, membawa kepada tingkah laku yang tidak dapat diramalkan.
Penyelesaian: Konvensyen Konsisten
Kuncinya ialah konsisten. Ubah suai perisytiharan fungsi C untuk menggunakan __cdecl
secara eksplisit: Gantikan extern "C" int __stdcall InvokedFunction(int);
dengan extern "C" int __cdecl InvokedFunction(int);
. Kemudian, pastikan atribut C# DllImport
anda sepadan:
<code class="language-csharp">[DllImport("CPlusPlus.dll", ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]</code>
Pengambilan Utama
Perhatian yang teliti terhadap konvensyen panggilan adalah penting untuk kesalingoperasian P/Invoke yang boleh dipercayai. Menggunakan konvensyen yang konsisten antara C dan C# menghapuskan ketidakseimbangan tindanan dan meningkatkan keteguhan keseluruhan kod anda.
Atas ialah kandungan terperinci Mengapa __stdcall C dan CDECL C# memanggil konflik di p/invoke, dan bagaimanakah ini dapat diselesaikan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!