C++/CLI中的事件处理

Eri*_*inn 0 .net events c++-cli event-handling

我有一个函数singleFrameEventHandler,我希望在某个事件OnNewFrame发生时调用它.在做了一些研究之后,在我看来,处理事件的函数具有void返回类型并且采用包含事件的类型的参数.从我在网上找到的,这是这样做的:

功能声明:

void singleFrameEventHandler(IAFrame ^ frame);
Run Code Online (Sandbox Code Playgroud)

分配函数以处理事件时:

iaframe->OnNewFrame += &singleFrameEventHandler;
Run Code Online (Sandbox Code Playgroud)

当我尝试编译包含上述段的代码时,我收到以下错误:

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
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

newFrame构造函数(?)似乎是最好的选择,因为它似乎采用了方法指针,但当我尝试使用它时:

iaframe->OnNewFrame += gcnew newFrame(iaframe, &singleFrameEventHandler);
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

error C3352: 'singleFrameEventHandler' : the specified function does not match the delegate type 'void (void)'
Run Code Online (Sandbox Code Playgroud)

这是否意味着我的函数不占用参数?如果是这样,我如何获得有关该事件的信息?

Bra*_*ger 6

.NET中的事件处理程序通常使用两个参数定义(请参阅MSDN)

delegate void EventHandler(object sender, EventArgs e)
Run Code Online (Sandbox Code Playgroud)

但是,您发布的错误消息强烈暗示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
    }
};
Run Code Online (Sandbox Code Playgroud)