Кто-нибудь заметил, что accepted answer работает только с тривиальными случаями? Единственный способ, которым функция <> :: target() возвращает объект, который может быть привязан к обратному вызову C, - это если он был сконструирован с объектом, который может быть связан с обратным вызовом C. Если это так, то вы могли бы связать его напрямую и пропустить всю функцию <> ерунда для начала.
Если вы думаете об этом, нет волшебного решения. Обратный вызов C-стиля хранится как один указатель, который указывает на исполняемый код. Для любой нетривиальной функции boost :: function <> потребуется по крайней мере два указателя: один для исполняемого кода, другой - данные, необходимые для настройки вызова (например, указатель «this» в случае связанного члена функция).
Правильный способ использования boost :: function и boost :: bind с обратными вызовами C заключается в создании функции прокладки, которая удовлетворяет сигнатуре обратного вызова, определяет, какую функцию <> позвонить и называет. Обычно обратные вызовы C будут иметь какой-то вид void * для «пользовательских данных»; вот где вы копить ваш указатель функции:
typedef void (*CallbackType)(int x, void* user_data);
void RegisterCallback(CallbackType cb, void* user_data);
void MyCallback(int x, void* userData) {
boost::function<void(int)> pfn = static_cast<boost::function<void(int)> >(userData);
pfn(x);
}
boost::function<void(int)> fn = boost::bind(myFunction(5));
RegisterCallback(MyCallback, &fn);
Конечно, если ваш обратный вызов подписи не включает в себя какой-то указатель данных пользователя, вы не повезло. Но любой обратный вызов, который не включает указатель пользовательских данных, уже неприменим в большинстве сценариев реального мира и нуждается в перезаписи.
единственный способ получить данные в обратном вызове, не привязывая его к нему, через бесплатный объект – 2009-02-05 04:29:21