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

Я пытаюсь добавить некоторый управляемый код в существующее приложение на языке c ++.Я хотел бы, чтобы работал функциональный обратный вызов ... в частности, я хотел бы передать указатель метода из НЕИЗМЕНЕННОГО кода в УПРАВЛЯЕМЫЙ код и заставить управляемый код вызывать обратный вызов.

Я смотрю начто-то вроде этого:

typedef int (__stdcall *ANSWERCB)(int);  //Delegate declaration

class UnmanagedObject
{
public:

 UnmanagedObject() {}
 int MethodD(int n) { return n; }
};

с соответствующим управляемым классом:

public delegate int CallbackDelegate(int i);

public class ManagedClass
{
    public ManagedClass() {}
    public void MethodD( CallbackDelegate cd ) { cd.Invoke( 5 ); }
}

Проблема в том, что я не могу понять, как на самом деле вызвать это из управляемогокод:

UnmanagedObject* obj = new UnmanagedObject();
ManagedLibrary::ManagedClass^ mc = gcnew ManagedLibrary::ManagedClass();
mc->MethodD( /* what do I pass here? */ );

Я пробовал:

ManagedLibrary::CallbackDelegate^ cd = gcnew CallbackDelegate(obj, &UnmanagedObject::MethodD);

, но он генерирует ошибку компилятора "цель делегата должна быть указателем на функцию-член".

Любой гуру взаимодействия может помочь?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 01 сентября 2010

Проблема начинается с объявления вашего указателя функции ANSWERCB. На самом деле он не подходит для вызова функции MethodD (), это метод экземпляра класса. Сначала сделайте эту работу на родном C ++, вам нужен указатель на функцию-член.

Оттуда у вас будет намного меньше проблем с его работой из управляемого кода, Marshal :: GetDelegateForFunctionPointer () даст вам то, что вам нужно.

0 голосов
/ 01 сентября 2010

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

class UnmanagedObject
{
public:
    UnmanagedObject() {} 
    int MethodD(int n) { return n; } 
};

Я подозреваю, что для вызова gcnew у вас просто неверные параметры - то есть, mem func ptr, затем obj.

...