Rumah > pembangunan bahagian belakang > C++ > Bagaimana untuk Mengelakkan System.AccessViolationException Apabila Melepasi Rentetan Antara C# dan C DLL?

Bagaimana untuk Mengelakkan System.AccessViolationException Apabila Melepasi Rentetan Antara C# dan C DLL?

DDD
Lepaskan: 2025-01-02 19:01:38
asal
252 orang telah melayarinya

How to Avoid System.AccessViolationException When Passing Strings Between C# and a C   DLL?

Melalui Rentetan antara C# dan C DLL: Contoh Minimal

Pernyataan Masalah

Walaupun mengikut pendekatan yang kelihatan mudah, menghantar rentetan antara C# dan C DLL melalui interop menyebabkan System.AccessViolationException. Kod dalam kedua-dua bahasa kelihatan betul, menimbulkan kekeliruan tentang punca isu.

Kod C

Kod C mentakrifkan fungsi, concat, yang menggabungkan dua rentetan dan mengembalikan hasilnya. Fungsi ini ditandakan untuk eksport ke DLL menggunakan __declspec(dllexport).

extern "C" {
    string concat(string a, string b){
        return a + b;
    }
}
Salin selepas log masuk

Kod C#

Dalam C#, kod mengimport fungsi concat menggunakan DllImport. CallingConvention ditetapkan kepada Cdecl untuk memadankan konvensyen C.

[DllImport("*****.dll", CallingConvention = CallingConvention.Cdecl)]
static extern string concat(string a, string b);
Salin selepas log masuk

Pengecualian dan Analisis

Memanggil concat("a", "b") dalam lontaran C# a System.AccessViolationException. Pengecualian ini menunjukkan bahawa akses memori tidak sah berlaku dalam kod asli.

Penyelesaian: Jenis Interop-Compatible

Penyebab isu ini terletak pada penggunaan C std :: rentetan merentasi sempadan interop. C# tidak boleh mencipta atau mengendalikan objek std::string secara langsung. Sebaliknya, jenis serasi interop mesti digunakan untuk pertukaran data.

Jenis Data Mesra Interop

Jenis interop yang sesuai termasuk tatasusunan aksara yang ditamatkan nol untuk menghantar rentetan daripada C# kepada C . Apabila menghantar rentetan daripada C ke C#, StringBuilder boleh digunakan, dengan pemanggil memperuntukkan penimbal dan penerima menulis ke dalamnya.

Kod Diubahsuai

Dalam C , fungsi concat boleh diisytiharkan dengan parameter char* dan int untuk menerima penimbal dannya panjang.

extern "C" {
    void concat(char *str, int len)
    {
        // Concatenate strings and write to buffer
    }
}
Salin selepas log masuk

Dalam C#, StringBuilder boleh digunakan.

[DllImport("...", CallingConvention = CallingConvention.Cdecl)]
static extern void concat(StringBuilder str, int len);

....

StringBuilder sb = new StringBuilder(10);
concat(sb, sb.Capacity);
Salin selepas log masuk

Dengan menggunakan jenis rentetan serasi interop, pertukaran rentetan antara C# dan C DLL boleh dipermudahkan dengan berkesan.

Atas ialah kandungan terperinci Bagaimana untuk Mengelakkan System.AccessViolationException Apabila Melepasi Rentetan Antara C# dan C DLL?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan