Я хочу вызвать делегат C # из неуправляемого кода C ++.Делегат без параметров работает нормально, но делегат с параметрами разбил мою программу - PullRequest
4 голосов
/ 30 июля 2010

Ниже приведен код функции из неуправляемой DLL. Он принимает указатель на функцию в качестве аргумента и просто возвращает значение, возвращаемое вызываемой функцией.

extern __declspec(dllexport) int  _stdcall callDelegate(int (*pt2Func)());
extern __declspec(dllexport) int  _stdcall callDelegate(int (*pt2Func)())
{
    int r = pt2Func();
    return r;
}

В управляемом коде C # я вызываю вышеупомянутую функцию umanged с делегатом.

  unsafe public delegate int mydelegate( );

    unsafe public int delFunc()
    {
             return 12;
    }

    mydelegate d = new mydelegate(delFunc);
    int re = callDelegate(d);
   [DllImport("cmxConnect.dll")]
    private unsafe static extern int callDelegate([MarshalAs(UnmanagedType.FunctionPtr)] mydelegate d);

Это все прекрасно работает !! но если я хочу, чтобы мой указатель / делегат функции принимал аргументы, это привело к сбою программы. Поэтому, если я изменю код следующим образом, моя программа вылетает.

Модифицированный неуправляемый c ++ -

extern __declspec(dllexport) int  _stdcall callDelegate(int (*pt2Func)(int));
extern __declspec(dllexport) int  _stdcall callDelegate(int (*pt2Func)(int))
{
    int r = pt2Func(7);
    return r;
}

Модифицированный код C # -

unsafe public delegate int mydelegate( int t);

        unsafe public int delFunc(int t)
        {
                 return 12;
        }

        mydelegate d = new mydelegate(delFunc);
        int re = callDelegate(d);

Ответы [ 2 ]

3 голосов
/ 30 июля 2010

Соглашение о вызовах для указателя функции неверно.Сделайте так, чтобы это выглядело так:

 int (__stdcall * pt2Func)(args...)
0 голосов
/ 01 февраля 2016

Так что это должно работать:

C ++ DLL:

extern "C" __declspec(dllexport) void __stdcall doWork(int worktodo, int(__stdcall *callbackfunc)(int));

C # Код:

delegate int del (int work);    

[DllImport(@"mydll")]
private static extern void doWork(int worktodo, del callback); 

int callbackFunc(int arg) {...} 

...

del d = new del(callbackFunc);
doWork(1000, d);
...