对成员函数的回调

Callback to a member function

本文关键字:回调 函数 成员      更新时间:2023-10-16

我有一个带有此签名的回调(我正在使用Live555):

typedef void(RTSPClient::responseHandler)(RTSPClient*, ...); //... = other parameters

然后在我的代码中,我按照库规则创建了 RTSPClient 的子类:

class MyRTSPClient: public RTSPClient { 
... 
//callback 
void continueAfterDESCRIBE(RTSPClient *client, ...); //same signature of typedef
...
};

现在问题来了。

在我的代码中,我必须调用以下方法:

unsigned RTSPClient::sendDescribeCommand(responseHandler, ...); //response handler is the typedef

如果我创建一个对象:

MyRTSPClient *client = MyRTSPClient::createNew(...); //is library requirement such creation

如何将函数对象作为回调传递给sendDescribeCommand

当然,如果我将continueAfterDESCRIBE声明为静态成员,我没有任何问题,但我想要一个对象,因为我有很多线程,如果我使用从它们调用的静态回调,就会引发许多同步问题。

所以我正在努力(作为C++的新手)如何找出正确的签名以传递obj->method作为回调。

不能将非静态成员函数用作需要常规函数的回调参数,因为它们的签名不兼容:

  • 非成员或静态成员函数仅采用其签名中的参数
  • 非静态成员函数为调用它的对象采用额外的"隐藏"参数。

仅当执行回调的库允许您使用回调注册传递自定义参数时,才可以使用此问题的常见解决方法。这通常使用 void* 指针完成,您在注册回调时将其传递给库,然后库在回调函数时将其传回给您。

方法如下:

// This is the static function that you register for your callback
static void staticContinueAfterDESCRIBE(RTSPClient *client, ...) {
    static_cast<MyRTSPClient*>(client)-> continueAfterDESCRIBE(client, ...);
}

现在该函数是静态的,您可以毫无问题地将其注册为回调。函数获取控件后,它会client强制转换为MyRTSPClient*类,并执行非静态回调。

您需要两个指针,一个指向对象,一个指向成员函数:

void (RTSPClient::*mfptr) = &RTSPClient::continueAfterDESCRIBE;

一个对象:

RTSPClient* p = new RTSPClient();

然后调用它:

p->*mfptr(...);