Menggunakan P/Invoke untuk memanggil fungsi C daripada C# boleh menyebabkan ranap sistem jika konvensyen panggilan tidak sepadan. Artikel ini meneroka sebab di sebalik konflik ini.
Memanggil Konvensyen Tidak Padan dan Kesannya
Senario biasa melibatkan fungsi C menggunakan konvensyen __stdcall
, manakala atribut C# DllImport
yang sepadan menentukan CallingConvention.Cdecl
. Ini berlaku kerana:
__stdcall
: Konvensyen panggilan standard untuk API Windows dan banyak fungsi C. Fungsi yang dipanggil (callee
) bertanggungjawab untuk membersihkan tindanan. Ini ialah lalai P/Invoke.__cdecl
: Digunakan dalam kod C. Fungsi panggilan (caller
) bertanggungjawab untuk pembersihan tindanan.Masalahnya: Ketidakseimbangan Timbunan
Apabila pemanggil dan penerima tidak bersetuju tentang pembersihan tindanan, ketidakseimbangan tindanan akan berlaku. Ini membawa kepada ranap sistem, gelagat yang tidak dapat diramalkan dan penyahpepijatan yang tidak boleh dipercayai disebabkan maklumat tindanan yang hilang.
Konvensyen Panggilan Lain (dan Mengapa Ia Penting)
__thiscall
: Digunakan dalam C untuk fungsi ahli. Ia tidak disokong secara langsung dalam .NET P/Invoke kerana kerumitan warisan dan perbezaan pengkompil.__fastcall
: Menggunakan daftar CPU untuk menghantar hujah. Tidak disokong dalam kod terurus.__clrcall
: Konvensyen kod terurus, menggabungkan aspek __stdcall
, __cdecl
dan __fastcall
, dengan pemeriksaan keselamatan masa jalan.Mengapa Konvensyen P/Invoke Lalai Boleh Menyebabkan Masalah
Konvensyen panggilan P/Invoke lalai (stdcall
) sering bertembung dengan kod C yang disusun menggunakan __cdecl
. Ini berpunca daripada perkaitan sejarah __stdcall
dengan API Windows, yang membawa kepada andaian (salah) bahawa semua fungsi C menggunakannya. Ketidakpadanan ini menyebabkan isu pembersihan tindanan yang diterangkan di atas.
Atas ialah kandungan terperinci Kenapa panggilan C# P/Invoke menggunakan `cdecl` kadang -kadang kemalangan ketika interfacing dengan fungsi` __stdcall` c?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!