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
220 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!

sumber:php.cn
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