C #: как получить двойной указатель на структуру из обратного вызова неуправляемой функции C ++ - PullRequest
0 голосов
/ 19 декабря 2010

Я буду лаконичен. У меня есть библиотека, написанная на C ++ с использованием openCV lib. Одна из моих функций:

EXTERN_HEADER HWND createHandle(FListener fl);

где FListener - указатель на функцию обратного вызова, определяемый как:

typedef void (__stdcall *FListener)
(int fSN, int fC, byte* fSData, IplImage **fS);

IplImage является структурой openCV.

Я пытаюсь использовать эту библиотеку и эти функции в C #, поэтому я DllImport-ing как таковой:

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate void FListener(int fSN, int fC, ref byte fSData, ref IntPtr fS);

[DllImport("FLib.dll", CharSet = CharSet.Auto, 
CallingConvention = CallingConvention.Cdecl)]
static extern int createHandle(FListener fl);

и, наконец, я объявляю метод, который будет вызываться обратно в мою программу на c #:

private void test(int fSN, int fC, ref byte fSD, ref IntPtr fS)
{
    //how -for the love of God- do I access that openCV double pointer struct 
    //inside "fS"?
}

Естественно, fS - это указатель на массив указателей, указывающих на IplImages. Должен ли я снова объявлять структуру IplImage внутри моего кода C #? Я не хочу использовать какую-либо оболочку C # для openCV. Я хочу, чтобы все было "чисто" и "просто" но я полностью застрял с составной частью ... Любая помощь будет оценена.

ОБНОВЛЕНИЕ: если я передаю массив fS как IntPtr *, он работает как шарм. Элементы извлекаются как fS [0], fS [1] и т. Д. Если я передаю его как «ref IntPtr», то первый элемент может быть получен как fS, но где я могу найти второй e.t.c.? Я попытался fS + Marshal.SizeOf (typeof (IplImage)) без удачи ... есть идеи?

Нет идей вообще?

Ответы [ 2 ]

0 голосов
/ 19 декабря 2010

Что касается вашего второго вопроса, вы можете получить доступ к другим элементам, используя метод IntPtr.ToPointer () в небезопасном коде, так что у вас будет указатель на базу структуры / массива указателей или чего-либо еще, а затем Можно просто использовать индексатор для доступа к ним, например:

int* p = (int*)fS.ToPointer();
p[3] = ...;

если указатель на массив IntPtrs делает то же самое, ToPointer еще раз.

0 голосов
/ 19 декабря 2010

Прошло много времени с тех пор, как я сделал Платформу, но я думаю, что ваш обратный вызов должен быть небезопасным, например,

unsafe delegate void FListener(int fSN, int fC, ref byte fSData, IplImage **fS);

Возможно, это не точный синтаксис, но он должен заставить вас двигаться в правильном направлении.

...