Как передать делегат ^ собственному классу в c / cli

#c #c 11 #c -cli

#c #c 11 #c -cli

Вопрос:

У меня есть собственный класс

 public NativeClass:
{
public:
    typedef void(*Func)(cv::UMat image);

    void setFunc(Func func);
}
  

и хотел бы передать функцию в качестве параметра из управляемого класса.

 ref ManagedClass:
{
    public:
        ManagedClass()
        {
           NativeClass* nativeClass = new NativeClass();
           nativeClass.setFunc(doSomething);
        }


    private:
        doSomething(cv::UMat image)
        {
            //do something
        }
}
  

Но, похоже, это не работает. Как я могу заставить это работать?

Ответ №1:

Прежде чем передавать делегат в качестве указателя на функцию, вам нужно сначала создать делегата.

В C # вам просто нужно ссылаться на имя метода без круглых скобок. В C / CLI вам нужно явно вызвать конструктор делегата, и вам нужно передать явные параметры объекта для вызова метода, и метод в стиле C .

 MyDelegate^ del = gcnew MyDelegate(this, amp;ManagedClass::doSomething);
// Explicit ctor  ^^^^^^^^^^^^^^^^
// Pass the object to be called on ^^^^
// Pass the method in the C   style      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  

Как только у вас это будет, вы можете просто передать делегат методу, который принимает необработанный указатель на функцию. Он знает, как преобразовать объект управляемого делегата в указатель на функцию. В документации Microsoft есть хороший пример. Вы должны быть уверены, что объект управляемого делегата всегда будет находиться рядом. Как только управляемый делегат собирается мусором, необработанный указатель функции перестает работать.

Как только у вас это будет, вам нужно будет посмотреть на ваш тип параметра, cv::UMat . Я не знаю, что это за тип или откуда вы его получаете, но вам может потребоваться настроить тип вашего параметра на управляемой стороне, неуправляемой стороне или обоих. (Вот почему я не объявлял тип делегата в моем примере выше; я не был уверен, что сработает, поэтому я оставил его универсальным. Если все работает, то вы можете использовать Action<cv::UMat> его в качестве своего типа делегата.)

Комментарии:

1.Спасибо вам за ваш ответ. Я написал следующий код delegate void MyDelegate(cv::UMat image); MyDelegate^ d = gcnew MyDelegate(this, amp;ManagedClass::doSomething); nativeClass->setFunc(d); , но он выдает ошибку E0167 аргумент типа «ManagedClass::MyDelegate ^» несовместим с параметром типа «NativeClass::Func» в setFunc(d); строке. Я также пытаюсь удалить cv::UMat параметр в Func и и MyDelegate . Но он выдает эту ошибку. У вас есть какие-нибудь идеи? Спасибо.