【问题标题】:use callback for member function对成员函数使用回调
【发布时间】:2017-09-25 13:25:09
【问题描述】:

编辑:(9 月 26 日)

对于触摸屏校准工具,我有一个 MT_Interface 类,它有一个成员函数Send_Touch_Event。每次调用此函数时,我都想从不同的类(Calibration_checker)运行一个名为“EventWrite”的回调函数。

在代码中,这些是感兴趣的函数(我想,我没有制作MT_Interface)。

class MT_Interface 
{
          void SetCallback( void (*cb)(MT_Interface_TouchEvent_Type), void* o ) {Callback_fct = cb; Callback_obj = o;};
          void Send_Touch_Event(MT_Interface_Message_Type Message, int ID, int X, int Y, int Additional_Info1, int Additional_Info2);
          {
            // Does something and than uses the callback
               (*Callback_fct)(touch_event, Callback_obj);
          };
}

带有EventWrite函数的类可以概括为:

class Calibration_checker 
{

    MT_Interface *MT_Interface_object  

    EventWrite(MT_Interface_TouchEvent_Type t, void* o)

    Configure()
    {
     // Configure the MT_Interface_object & set callback    
     MT_Interface_object->SetCallback(&Calibration_checker::EventWrite, (void*)this);
     }
}

我认为这里要使用 SetCallBack 函数,但我无法让它工作。我不太明白我收到的错误信息。也许这里有人可以阐明这个问题?

不幸的是,当我应用下面建议的包装函数时,我得到了类似的错误。

Calibration_checker.cxx: In member function ‘void Calibration_checker::Configure()’:
Calibration_checker.cxx:83:81: error: no matching function for call to ‘MT_Interface::SetCallback(void (Calibration_checker::*)(MT_Interface_TouchEvent_Type, void*), void*)’
   MT_Interface_object->SetCallback(&Calibration_checker::EventWrite, (void*)this);
                                                                                 ^
In file included from Calibration_checker.hxx:4:0,
                 from Calibration_checker.cxx:4:
MT_Interface.hxx:163:12: note: candidate: void MT_Interface::SetCallback(void (*)(MT_Interface_TouchEvent_Type, void*), void*)
       void SetCallback( void (*cb)(MT_Interface_TouchEvent_Type, void*), void* o ) {Callback_fct = cb; Callback_obj = o;};
            ^
MT_Interface.hxx:163:12: note:   no known conversion for argument 1 from ‘void (Calibration_checker::*)(MT_Interface_TouchEvent_Type, void*)’ to ‘void (*)(MT_Interface_TouchEvent_Type, void*)’

【问题讨论】:

  • 你能创建一个 lambda 并将其作为回调传递吗?然后你可以在那里捕获任何东西并执行你想要的任何代码。
  • 简而言之:指向函数的指针是不够的,您还必须将引用/指针传递给对象(以显式方式作为参数或通过函子对象)来自相关列表:stackoverflow.com/questions/2298242/…

标签: c++ object callback


【解决方案1】:

非静态成员函数不能作为函数指针存在,因为this 指针需要以某种方式传递。值得庆幸的是,看起来o 参数被传递回回调函数,因此将对象作为第二个参数传递,将包装函数作为第一个参数传递应该可以解决问题。

鉴于这种类型:

struct Foo
{
    void EventWrite(MT_Interface_TouchEvent_Type);
};

还有这个包装函数:

void foo_touch_event_wrapper(MT_Interface_TouchEvent_Type t, void *o)
{
    static_cast<Foo *>(o)->EventWrite(t);
}

还有一些实例foo在调用回调时仍然存在,那么我们可以附加处理程序:

someObject.SetCallback(foo_touch_event_wrapper, &foo);

【讨论】:

  • 感谢您的建议。我不明白你为什么使用 *o 参数。在原始代码中,有一个用于不同目的的 SetCallback 函数(假设已校准触摸屏):其中 void 指针 o 用于访问在另一个类中定义的成员变量(校准系数)。在这种情况下,我不需要这个参数(我认为),因为我只想使用 MT_Interface_TouchEvent_Type 输出。因此,我真的不知道如何应用包装器选项。
  • @Simon 但是EventWrite 是类的成员函数,对吗?如果是这样,我们使用o 参数来传递调用EventWrite的对象
  • 很遗憾,Eventwrite 不是类的成员函数。我需要 EventWrite 做的就是提取 X 和 Y 位置并将它们添加到一个变量中(稍后对其进行平均以获得对屏幕上给定点的更好校准)。不过,我可以为它制作一个校准课程。将检查这是否可行:)
  • @Simon 那么我实际上根本不知道你的问题在问什么,而且标题(“成员函数的回调函数”)不仅具有误导性,而且完全错误。请编辑您的问题以包含明确的问题/问题陈述。
  • 我将编辑标题,但如果我没记错的话,我的帖子应该很清楚。 “如何使用‘普通’/非成员函数作为类成员函数(在本例中为 MT_Interface)的回调?”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多