У меня есть обратный вызов с этой подписью (я использую 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(...);