#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, можно написать библиотеку-обертку, которая будет преобразовывать неудобный формат в удобный. Например, можно в обертке принимать массив строк, а выдавать строки по отдельности.
Комментариев нет:
Отправить комментарий