【问题标题】:Event Handling in C++/CLIC++/CLI 中的事件处理
【发布时间】:2010-08-13 14:15:02
【问题描述】:

我有一个函数,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)'

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

【问题讨论】:

    标签: .net events event-handling c++-cli


    【解决方案1】:

    .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】:

      第一个语法不起作用,这是 C++/CLI 所没有的 C# 语法糖。

      第二个 sn-p 的问题是委托类型与事件处理程序的签名不匹配。委托是这样声明的:

       delegate void newFrame();
      

      您必须将方法签名更改为:

       void singleFrameEventHandler() 
       {
          // etc..
       }
      

      从您的 sn-ps 中不清楚您应该如何获得对框架的引用。我猜是类上的一个属性。

      【讨论】:

      • 好的,谢谢。我还发现,当我从工厂获得一个 IAFrame(除了事件之外还包括单个帧的数据)时,我得到了最新的帧,所以我不需要事件处理程序来拥有 IAFrame 对象句柄传递给它。
      猜你喜欢
      • 1970-01-01
      • 2013-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-11
      • 1970-01-01
      相关资源
      最近更新 更多