Страницы

Поиск по вопросам

четверг, 20 декабря 2018 г.

Как передать в C# массив строк из неуправляемой библиотеки?

Привет! Функция на C в DLL (которую я не могу менять), возвращает массив строк. Число элементов массива заранее неизвестно и может быть от 0 до 255. #define MAX_ARRAY_SIZE 255
// // Возвращает длину массива (количество строк) // LONG GetStringArray(char **Array); Реально ли вообще передать такие данные через P/Invoke? Если да, то как подступиться к задаче?


Ответ

Самый удобный способ это по совету wow использовать Managed C++ и написать обертку оттуда. Можно и сделать чуть более криво примерно так(я добавил ссылку на входной массив, чтобы не использовать внешнюю функцию инициализации, которая необходима при вашем описании GetStringArray ) как: С++ extern "C" __declspec(dllexport) LONG StringFunc(char** &data);
LONG StringFunc(char** & data) { LONG count = 2; data = new char*[count]; data[0] = new char[10]; data[1] = new char[10]; strcpy(data[0], "str1"); strcpy(data[1], "bla bla1"); return count;
} С#: [DllImport(@"..\..\..\..\debug\NativeDll.dll")]
public static extern LONG StringFunc(ref IntPtr data);
public static String[] CallNative() { IntPtr ptr_start = IntPtr.Zero; LONG count = StringFunc(ref ptr_start);
//массив указателей на строки IntPtr []ptr_strings = new IntPtr[count]; //копируем указатели на строки Marshal.Copy(ptr_start, ptr_strings, 0, count); String[] strings = new string[count];
for (int i=0;i< count; i++) { strings[i] = Marshal.PtrToStringAnsi(ptr_strings[i]); }
return strings; }
static void Main(string[] args) { String[] strings = CallNative(); Array.ForEach(strings, s => Console.WriteLine(s)); }

Комментариев нет:

Отправить комментарий