Saya telah menulis pustaka C++ dasar yang mengambil data dari server OPC UA dan memformatnya menjadi array string (char **). Saya telah mengonfirmasi bahwa ini berfungsi mandiri, tetapi sekarang saya mencoba memanggilnya dari program C# menggunakan DLL/pInvoke dan mengalami kesalahan memori yang serius.
C # utama saya:
List<String> resultList = new List<string>();
IntPtr inArr = new IntPtr();
inArr = Marshal.AllocHGlobal(inArr);
resultList = Utilities.ReturnStringArray(/*data*/,inArr);
Fungsi pembantu C#:
public class Utilities{
[DllImport(//DllArgs- confirmed to be correct)]
private static extern void getTopLevelNodes(/*data*/, IntPtr inArr);
public static List<String> ReturnStringArray(/*data*/,IntPtr inArr)
{
getTopLevelNodes(/*data*/,inArr); // <- this is where the AccessViolationException is thrown
//functions that convert char ** to List<String>
//return list
}
Dan terakhir, implementasi C++ DLL saya:
extern "C" EXPORT void getTopLevelNodes(*/data*/,char **ret){
std::vector<std::string> results = std::vector<std::string>();
//code that fills vector with strings from server
ret = (char **)realloc(ret, sizeof(char *));
ret[0] = (char *)malloc(sizeof(char));
strcpy(ret[0], "");
int count = 0;
int capacity = 1;
for (auto string : results){
ret[count] = (char*)malloc(sizeof(char) * 2048);
strcpy(ret[count++], string.c_str());
if (count == capacity){
capacity *= 2;
ret = (char **)realloc(ret, sizeof(char *)*capacity + 1);
}
}
Apa yang harus dilakukan adalah, inisialisasi Daftar untuk menampung hasil akhir dan IntPtr untuk diisi sebagai char ** oleh C++ DLL, yang kemudian diproses kembali dalam C# dan diformat menjadi Daftar. Namun, AccessViolationException muncul setiap kali saya memanggil getTopLevelNodes dari C#. Apa yang dapat saya lakukan untuk memperbaiki masalah memori ini? Apakah ini cara terbaik untuk meneruskan array string melalui interop?
Terima kasih sebelumnya
Sunting: Saya masih mencari jawaban lain, jika ada cara yang lebih sederhana untuk mengimplementasikan interop array string antara C# dan DLL, beri tahu saya!
IntPtr[]
alih-alihIntPtr
karena Anda, dalam arti tertentu, meneruskan serangkaian pointer, bukan hanya satu pointer. Selain itu, sebagai catatan tambahan, saya yakin Anda mengalami kebocoran memori sebesar 1 karakter untuk elemen array pertama Anda, karena Anda mencari tempat untuk itu, lalu panggil malloc lagi pada iterasi pertama loop Anda. - person pstrjds   schedule 20.12.2016