Pengecualian penunjuk tidak valid menggunakan pinvoke di libnfc untuk nilai string [duplikat]

Saya mencoba berkomunikasi dengan pembaca/penulis NFC di raspberry pi 3 menggunakan inti dotnet.

Saya harus mengatakan bahwa berbagai alat baris perintah libnfc yang saya gunakan semuanya berfungsi dengan baik (alias saya dapat membaca dan melakukan polling tag saya, tidak ada masalah di sisi ini).

Idenya adalah menggunakan inti dotnet dan C# untuk mengatur perpustakaan libnfc dan tampaknya berfungsi dengan baik kecuali segera setelah fungsi yang saya panggil mengembalikan string, saya mendapatkan pesan kesalahan berikut:

*** Error in `./NfcTest': free(): invalid pointer: 0x6d4ebc00 ***

Tentu saja NFCTest adalah nama aplikasi saya.

Berikut adalah definisi pinvoke

[DllImport("libnfc", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string nfc_version();

Harap dicatat bahwa setelah mencari di web saya sendiri menambahkan atribut [return] tetapi tidak mengubah apa pun pada hasilnya. Kesalahan yang sama muncul.

Kode nfc_version di libnfc ada di sini: https://github.com/nfc-tools/libnfc/blob/c3f739dea339a71c59d7d53ab6b0ecc477c3ab73/libnfc/nfc.c#L1325

Tampaknya mengembalikan konstan dan tidak melakukan pembebasan apa pun. Jadi tebakan saya adalah saya salah mengonfigurasi salah satu atribut.

Contoh lainnya adalah saya menyebut yang berikut ini:

[DllImport("libnfc", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern string nfc_device_get_name(IntPtr pnd);

Meskipun saya dapat dengan sempurna memanggil metode lain (yaitu jajak pendapat) menggunakan penunjuk (param pnd), pemanggilan ini mengembalikan kesalahan yang sama seperti pada metode Versi. Kedua metode mengembalikan string membuat saya bertanya-tanya apakah masalahnya bukan di DllImport tetapi saya tidak terlalu yakin bagaimana cara memperbaikinya.

Tautan ke kode lib untuk contoh itu: https://github.com/nfc-tools/libnfc/blob/c3f739dea339a71c59d7d53ab6b0ecc477c3ab73/libnfc/nfc.c#L1215

Kebijaksanaan apa pun akan sangat dihargai.


person Georges Legros    schedule 23.02.2021    source sumber
comment
Bacalah ini. Kemungkinan Anda perlu mengembalikan IntPtr dan menyusunnya sendiri menjadi string.   -  person Matthew Watson    schedule 23.02.2021


Jawaban (1)


Komentar dari Matthew Watson dan tautan yang dia bagikan memiliki jawaban yang benar!

Jadi saya memodifikasi baris pinvoke seperti ini:

[DllImport("libnfc", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr nfc_version();

Lalu saya menyebutnya seperti ini:

public string Version()
{
    IntPtr ptr = Functions.nfc_version();
    var str = Marshal.PtrToStringAuto(ptr);
    return str;   
}

Dan itu bekerja dengan sangat baik!

Terima kasih!

person Georges Legros    schedule 23.02.2021