What is a callback function (callback)
Module A has a function foo, he passes the address of Foo to module B, and then a certain event occurs in B, by calling Foo from the address of Foo that is passed from a, informing a about what has happened and making a react accordingly. Then we call Foo the callback function.
Example:
The callback function is a very useful and important concept. When an event occurs, the system or other function automatically calls a function that you define. Callback functions are used in Windows programming in many situations, such as hook callback functions: Mouseproc,getmsgproc with enumwindows,drawstate callback function, etc., there are many system-level callback procedures. This article is not intended to introduce these functions and procedures, but rather to talk about some of the experience of implementing your own callback functions.
The idea of using a callback function is to use VC and Delphi mixed programming, a DLL written by VC for some time long asynchronous work, after the completion of the work, you need to notify the application of the DLL: some events have been completed, please handle the next part of the event. began to think of using synchronization objects, document mapping, messages, and other implementation of DLL functions to the application notification, and then suddenly thought can not be able to write a function on the application side, and so on the need to handle the subsequent matters, in the DLL directly call this function.
So he wrote a prototype of the callback function. Tested in both VC and Delphi.
One: Declares the callback function type.
VC version
typedef int (WINAPI *pfcallback) (int param1,int Param2);
Version Delph
Pfcallback = function (Param1:integer; Param2:integer): Integer;stdcall;
is actually declaring a pointer to a function that returns a value of int, passing in a parameter of two int.
Since the C + + and Pascal compilers are likely to be inconsistent with the processing of parameter-in-stack and function-return, the function type is WINAPI (WINAPI macro expansion is __stdcall) or stdcall uniform adornment.
Second: Declaring the callback function as a prototype
declaring function prototypes
VC version
int WINAPI cbfunc (int param1,int Param2);
Delphi Edition
function Cbfunc (Param1,param2:integer): Integer;stdcall;
The above function is a global function, and if you want to use a function in a class as the prototype of a callback function, declare the class function as a static function. [Page]
Three: callback function call caller
Functions that call the callback function I put him in the DLL, which is a very simple VC-generated WIN32 DLL. and use the DEF document to output its function name Testcallback. The implementation is as follows:
Pfcallback gcallback=0;
void WINAPI Testcallback (pfcallback Func)
{
if (func==null) return;
Gcallback=func;
DWORD threadid=0;
HANDLE hthread = CreateThread (null, NULL, THREAD1, LPVOID (0), &threadid);
Return
}
The work of this function saves the incoming pfcallback func parameter for use, and starts a thread. Declares a function pointer pfcallback gcallback to save the incoming function address.
Four: How the callback function is used:
After the Testcallback function is called, a thread is started, and as a demonstration, the thread is artificially deferred and the process of running the thread is printed on the screen.
The code for this thread is also implemented in the DLL project.
ULONG WINAPI Thread1 (LPVOID Param)
{
TCHAR buffer[256];
HDC hdc = GetDC (hwnd_desktop);
[NextPage]
int step=1;
MSG msg; [Page]
DWORD Starttick;
A delay loop
for (; step<200; step++)
{
Starttick = GetTickCount ();
for (; GetTickCount ()-starttick<10;)
{
if (PeekMessage (&msg,null,0,0,pm_noremove))
{
TranslateMessage (&MSG);
DispatchMessage (&MSG);
}
} [Page]
sprintf (buffer,/"Running d/", Step);
if (hdc!=null)
TextOut (Hdc,30,50,buffer,strlen (Buffer));
}
(*gcallback) (step,1);
:: ReleaseDC (HWND_DESKTOP,HDC);
return 0;
}
Five: everything has
Using VC and Delphi to establish a project, write the implementation of the callback function part
VC version
int WINAPI cbfunc (int param1,int Param2)
{
int res= param1+param2;
TCHAR buffer[256]=/"/";
sprintf (buffer,/"Callback result =%d/", res);
[NextPage]
MessageBox (null,buffer,/"testing/", MB_OK); The demo callback function is called
return res; [Page]
}
Delphi Edition
function Cbfunc (param1,param2:integer): integer;
Begin
Result:= param1+param2;
TFORM1.EDIT1.TEXT:=INTTOSTR (result); //Demo callback function is called
End
Use the static connection method to connect the Exit function in the DLL Testcallback, add the Button in the project (for the Delphi project, you also need to put an edit control on the Form1, the default name is Edit1).
Response ButtonClick Event Call Testcallback
Testcallback (CBFUNC)//function parameter cbfunc is the address of the callback function
The function call returns immediately after the thread is created, and the application can do something else at the same time. Now you can see the display string on the screen, indicating that the thread created in the DLL is working properly. After a while, the thread delay part ends, the VC application pops up the MessageBox, indicating that the callback function is called and displays the result of the param1,param2 operation, and the text in the Delphi program edit control is rewritten to PARAM1,PARAM2 Results of the operation.
It can be seen that the programming mode of the callback function is able to pass different callback function addresses according to different requirements, or to define the prototype of various callback functions (and also change the parameters and return value conventions using the callback function), and implement various callback event processing, which can make the control of the program flexible and efficient. A clear way of coupling between program modules. Especially useful in some asynchronous or complex programming systems-you can focus on the business process and technical functions of the module core in a module (such as a DLL), and the extended function of the periphery gives only the interface of a callback function, by invoking the address of the callback function passed by other modules. Seamlessly hand over the next process to another module, which is handled in a customized manner.
The example of this article uses a multithreaded delay in the DLL to call the callback function, just to highlight the effect of the callback function, in fact, as long as you are in this process, you can be happy with the function address passed to pass, as a callback function to use.
The principle of such a programming pattern is simple: to call a function as a pointer to an address, there is nothing else complicated, just a little trick in programming. As to how the callback function pattern can benefit you, it depends on whether or not you use the programming pattern. [Page]
An additional explanation: Cdxiaogan
This is what MSDN says:
Knowledge about function pointers
Use examples to illustrate the usage of function pointers. First, take a look at the EnumWindows function in the Win32 API:
Declare Function EnumWindows lib/"user32/" _
(ByVal Lpenumfunc as Long, _
ByVal LParam as Long) as long
EnumWindows is an enumeration function that lists the handles to each open window in the system. The way EnumWindows works is to repeatedly invoke the first argument passed to him (Lpenumfunc, function pointer). Whenever EnumWindows invokes a function, EnumWindows passes a handle to the open window.
When calling EnumWindows in code, a custom function can be passed to him as the first parameter to handle a series of values. For example, you can write a function that adds any value to a list box, converting the HWND value to the name of the window, along with any other action!
To indicate that the passed argument is a custom function, precede the function name with the ADDRESSOF keyword. The second parameter can be any value that is appropriate. For example, if you want to use MyProc as a function parameter, you can call EnumWindows as follows:
x = EnumWindows (AddressOf MyProc, 5)
The custom function that is specified when the procedure is called is called a callback function. A callback function (usually referred to as a "callback") can perform a specified action on the data provided by the procedure.
The parameter set of the callback function must have a prescribed form, which is determined by the API using the callback function. See the API documentation for what parameters you need and how to call them.
Reply Person: Zcchm
Let me talk about my own understanding of the callback function, the wrong place please advise.
When I first approached the callback, it was a fog. Many people explain this problem, always take the API to cite examples, originally rookie most feared is the API, ^_^. Callbacks are not necessarily associated with APIs.
In fact, a callback is a function call using a function pointer process.
Why use callbacks? For example, I'm going to write a submodule for you to receive commands from a remote socket. When I receive the command, I need to call the function of your main module to do the corresponding processing. But I don't know which function you're going to use to handle this command, I don't know what your main module is. cpp or. h, or, I don't have to care what you do with him in the main module, and you shouldn't care what function to handle him ... What to do?
[NextPage]
Use callbacks.
I'll define the callback function type in my module, along with the callback function pointer.
typedef void (CALLBACK *cbksendcmdtomain) (ansistring scmd);
Cbksendcmdtomain Sendcmdtomain;
So Sendcmdtomain is a pointer to a function that has a ansistring parameter and a return value of void.
Thus, when I receive the command, I am able to invoke this function. [Page]
...
Sendcmdtomain (Scommand);
...
But this is not enough, I have to give an interface function (such as init), let you call init in the main module to register the callback function.
In your main module, this May
void CALLBACK Yoursendcmdfun (ansistring scmd); Statement
...
void CALLBACK Yoursendcmdfun (ansistring scmd); Defined
{
ShowMessage (Scmd);
}
...
Call the INIT function to register a callback with my module. This could be:
Init (Yoursendcmdfun, ...);
In this way, the intended purpose is achieved.
It is important to note that callback functions are generally declared as global. If you want to use the callback function in the class, the previous need to add static, in fact, it is equivalent to the global.
Use of the C + + callback function (callback)