Привет!
Функция на 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));
}
Комментариев нет:
Отправить комментарий