Идиома для обратных вызовов C состоит в том, чтобы включать пользовательские данные , которые передают произвольный параметр через функцию и обратно в обратный вызов:
typedef void ( *FuncPtr )( int, uintptr_t user_data );
extern void MyFunc( FuncPtr callback, uintptr_t user_data );
При вызове метода в классе собратный вызов, который вы используете user_data
для передачи указателя this
:
class MyClass
{
public:
void SomeFunction( int n )
{
std::cout << "bla: " << n << std::endl;
}
private:
static void SomeFunctionEntry( int n, uintptr_t user_data)
{
MyClass *ths = (MyClass *) user_data;
ths->SomeFunction(n);
}
};
Статическая функция SomeFunctionEntry
является свободной функцией, которая может быть вызвана в качестве обратного вызова.Вы гарантируете, что его аргумент user_data
является допустимым экземпляром класса:
int main()
{
MyClass obj;
MyFunc(&MyClass::SomeFunctionEntry, (uintptr_t) &obj);
}
(примечание: это очень плохая идея для передачи автоматической переменной, такой как obj
, в качестве обратного вызовав многопоточной среде, потому что трудно быть уверенным, что указатель все еще будет действителен, когда обратный вызов в конечном счете вызывается)