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)
这是否意味着我的函数不占用参数?如果是这样,我如何获得有关该事件的信息?
.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)