Функции обратного вызова выполняют аналогичную задачу для делегатов в C #.
Например, Win32 API предоставляет службу синхронизации, доступ к которой осуществляется посредством вызова SetTimer.SetTimer экспортируется системной DLL, но механизм точно такой же, как если бы он использовался в пользовательской dll.В вашем коде вы можете получить доступ к таймеру, выполнив что-то вроде этого:
void
CALLBACK
MyTimerCallback(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
// do something
}
...
TIMERPROC fn = &MyTimerCallback;
int delay = 500;
SetTimer(NULL,0,delay,fn);
Вызов SetTimer и передача функции обратного вызова позволяет операционной системе вызывать функцию обратно каждый раз, когда срабатывает таймер.Конечно, здесь нет возможности многоадресной рассылки, и, особенно в случае SetTimer, функция обратного вызова должна быть функцией C или статическим методом класса.С этой функцией не связано ни одного экземпляра класса или объекта.
Подобный шаблон может быть выполнен в .NET - я уверен. В .NET есть своя собственная парадигма Timer, но на мгновение мы можем притвориться, что она реализует функцию SetTimerдля этого требуется TimerDelegate.
В пользовательском коде в объекте вы затем определяете MyTimerProc как функцию с сигнатурой, соответствующей делегату.И вызвать его так:
TimerDelegate d = new TimerDelegate(myObject.MyTimerProc);
SetTimer(0,0,delay,d);
Или, если «таймеры» были событием, которое соответствует TimerDelegate, то эквивалентный код C # будет выглядеть примерно так:
timers += new TimerDelegate(myObject.MyTimerProc);
Примечание: мойC # очень ржавый, поэтому не принимайте эти примеры кода в качестве какого-либо примера передового опыта или даже рабочего кода: P
При определении ваших собственных функций обратного вызова рекомендуется всегда определятьфункции обратного вызова принимают параметр void * "context", поскольку это позволяет программистам C ++ сохранять свой указатель "this" и извлекать его.
// the first parameter to the callback fn is a void* user supplied context parameter
typedef void (CALLBACK* MyCallbackFn)(void* context, int etc);
// and, the dll export function always takes a function pointer, context parameter pair.
DLL_EXPORT void SomeExportedFn(MyCallbackFn, void* context);