Обработка событий в C ++ / CLI - PullRequest
0 голосов
/ 13 августа 2010

У меня есть функция, singleFrameEventHandler, которую я хочу вызывать при возникновении определенного события OnNewFrame. После некоторого исследования мне показалось, что функции, которые обрабатывают события, имеют возвращаемый тип void и принимают параметр типа, который содержит событие. Из того, что я мог найти в Интернете, это делается так:

Объявление функции:

void singleFrameEventHandler(IAFrame ^ frame);

Когда функция назначена для обработки события:

iaframe->OnNewFrame += &singleFrameEventHandler;

Когда я пытаюсь скомпилировать код, содержащий вышеупомянутые сегменты, я получаю следующую ошибку:

error C2664: 'Spiricon::BeamGage::Automation::Interfaces::IAFrame::OnNewFrame::add' : cannot convert parameter 1 from 'void (__clrcall *)(Spiricon::BeamGage::Automation::Interfaces::IAFrame ^)' to 'Spiricon::BeamGage::Automation::Interfaces::newFrame ^'
No user-defined-conversion operator available, or
There is no context in which this conversion is possible

OnNewFrame имеет тип Spiricon :: BeamGage :: Automation :: Interfaces :: newFrame, который, к сожалению, не имеет документации, кроме того, что описывается как «Событие, которое вызывается, когда доступен новый кадр».

В браузере объектов я могу найти некоторую информацию об этом:

public delegate newFrame:
    public System.IAsyncResult BeginInvoke(System.AsyncCallback callback, System.Object object)
    public System.Void EndInvoke(System.IAsyncResult result)
    public System.Void Invoke()
    public newFrame(System.Object object, System.IntPtr method)

Конструктор newFrame (?) Кажется лучшим выбором, поскольку он принимает указатель на метод, но когда я пытаюсь использовать его следующим образом:

iaframe->OnNewFrame += gcnew newFrame(iaframe, &singleFrameEventHandler);

Я получаю следующую ошибку:

error C3352: 'singleFrameEventHandler' : the specified function does not match the delegate type 'void (void)'

Значит ли это, что моя функция не должна принимать никаких параметров? Если да, как я могу получить информацию о событии?

Ответы [ 2 ]

6 голосов
/ 13 августа 2010

Обработчики событий в .NET обычно определяются с двумя параметрами (см. MSDN )

delegate void EventHandler(object sender, EventArgs e)

Тем не менее, сообщения об ошибках, которые вы опубликовали, явно подразумевают, что OnNewFrame не следует этому шаблону и что singleFrameEventHandler не должно принимать никаких параметров.

Я предполагаю, что разработчики этого API подумали, что о самом событии было достаточно информации, и что обработчик события будет хранить ссылку на IAFrame, вызывающий событие, если ему потребуется запросить его. Код, подобный следующему, должен работать (обратите внимание, что при создании делегата обработчика событий вам нужно ссылаться на класс, владеющий методом обработчика событий, а не на исходный объект):

class FrameEventHandlers
{
public:
    FrameEventHandlers(IAFrame ^ frame)
      : m_frame(frame)
    {
        m_frame->OnNewFrame += gcnew newFrame(this, &FrameEventHandlers::singleFrameEventHandler);
    }

private:
    void singleFrameEventHandler()
    {
        // query m_frame for new data
    }
};
2 голосов
/ 13 августа 2010

Первый синтаксис не может работать, это синтаксис C #, которого нет в C ++ / CLI.

Проблема со вторым фрагментом заключается в том, что тип делегата не соответствует сигнатуре вашего обработчика событий. Делегат был объявлен так:

 delegate void newFrame();

Вам придется изменить подпись вашего метода на:

 void singleFrameEventHandler() 
 {
    // etc..
 }

Как вы должны получить ссылку на кадр, неясно из ваших фрагментов. Я бы предположил, на имущество в классе.

...