Страницы

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

вторник, 31 декабря 2019 г.

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

#c #pinvoke #c_sharp


Привет!
Функция на C в DLL (которую я не могу менять), возвращает массив строк. Число элементов
массива заранее неизвестно и может быть от 0 до 255.
#define MAX_ARRAY_SIZE 255

//
// Возвращает длину массива (количество строк)
//
LONG GetStringArray(char **Array);

Реально ли вообще передать такие данные через P/Invoke? Если да, то как подступиться
к задаче?    


Ответы

Ответ 1



Самый удобный способ это по совету 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)); }

Ответ 2



Посмотрите PInvoke Interop Assistant. Это набор инструментов по работе с pinvoke. Если окажется, что массив никак не протащить через pinvoke, можно написать библиотеку-обертку, которая будет преобразовывать неудобный формат в удобный. Например, можно в обертке принимать массив строк, а выдавать строки по отдельности.

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

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