Обратный вызов функции-члена

0

У меня есть обратный вызов с этой подписью (я использую 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 как статический член, у меня нет никаких проблем, но я хочу объект, потому что у меня много потоков, и если я использую статический callback, вызванный из них, многие проблемы синхронизации будут подняты.

Поэтому я борюсь (как новичок в C++), как узнать правильную подпись, чтобы передать obj->method в качестве обратного вызова.

Теги:
callback
live555

2 ответа

0
Лучший ответ

Вы не можете использовать нестационарную функцию-член как параметр обратного вызова, который ожидает регулярную функцию, потому что их подписи несовместимы:

  • Не член или статическая функция-член принимает только параметры в своей сигнатуре
  • Нестатическая функция-член принимает дополнительный "скрытый" параметр для объекта, на который он вызывается.

Общим решением для этого является возможность, только если библиотека, которая выполняет обратный вызов, позволяет передавать пользовательские параметры с регистрацией обратного вызова. Обычно это делается с помощью указателя void*, который вы передаете библиотеке при регистрации обратного вызова, а затем библиотека передает ее обратно, когда она вызывает обратную функцию.

Вот как это сделать:

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

Теперь, когда функция статична, у вас нет проблем с ее регистрацией в качестве обратного вызова. Как только функция получает элемент управления, он MyRTSPClient* client в ваш класс MyRTSPClient* и выполняет нестатический обратный вызов.

  • 0
    Спасибо, сэр. По вашему мнению, если я дал вам ваш ценный совет, работает ли каждый поток, который вызывает статический обратный вызов (как обертку, если я его не понял), с отдельным «continueAfterDESCRIBE», избегая меня синхронизировать их с методом?
  • 0
    @Chris Поскольку client передается обратно библиотекой, управление потоками также контролируется библиотекой: если у каждого потока есть собственный client , синхронизация не требуется. Если несколько потоков могут использовать один и тот же client , вам необходимо выполнить синхронизацию. В любом случае вам нужно будет синхронизировать continueAfterDESCRIBE , а не staticContinueAfterDESCRIBE , поскольку статическая оболочка никогда не обращается к каким-либо общим ресурсам явно.
0

Вам нужны два указателя: один для объекта и один для функции-члена:

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

и один к объекту:

RTSPClient* p = new RTSPClient();

а затем назовите его:

p->*mfptr(...);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню