From: http://blog.163.com/william_djj@126/blog/static/351665012009324114710982/
1. What is callback?
There are always some interfaces between software modules. In terms of calling methods, they can be divided into three types: Synchronous call, callback and asynchronous call. Synchronous call is a blocking call. The caller must wait for the other party to execute
It is a one-way call. Callback is a two-way call mode. That is, the called party also calls the interface of the other party when the interface is called; asynchronous calling is a mechanism similar to messages or events,
However, the calling direction is the opposite. When an interface service receives a message or an event, it proactively notifies the customer (that is, the customer's interface ). Callback and asynchronous call are closely related.
Callback is used to register asynchronous messages and message notifications are implemented through asynchronous calls. Synchronous calling is the simplest of the three, and callback is often the basis of asynchronous calling. Therefore, we will focus on
Implementation of adjustment mechanisms in different software architectures.
For different types of languages (such as structured and object languages), platforms (Win32, JDK), or architectures (such as CORBA, DCOM, and WebService ),
In addition to the synchronous mode, InterAction requires a certain asynchronous notification mechanism so that the service provider (or interface provider) can actively notify the customer in some situations, callback is the simplest way to implement Asynchronization.
For general structured languages, callback can be implemented through callback functions. The callback function is also a function or process, but it is implemented by the caller and used by the caller (as follows:
In the preceding example, the call back function fcallback is implemented in the same file by calling the getcallback function.
In other files. The intuitive understanding is to call getcallback (), but the actual implementation is in this module, so it is called callback ).
In an object-oriented language, callback is implemented through an interface or abstract class. We call the class implementing this interface a callback class, and the object of the callback class becomes the callback object. For object languages such as C ++ or Object Pascal that are compatible with the process features, they not only provide callback objects, callback methods, and other features, but also support the callback function mechanism of the Process language.
The message mechanism on the Windows platform can also be seen as an application of callback. We use the interface provided by the system to register the message processing function (that is, the callback function) to receive and process messages. Because Windows APIs are built in C language, we can think of them as a special case of callback functions.
For the Distributed Component proxy system (CORBA), asynchronous processing involves multiple methods, such as Callback, event service, and notification service. Event Service and notification service are the standard services used by CORBA to process asynchronous messages. They are mainly responsible for message processing, distribution, and maintenance. Some simple asynchronous processing processes can be implemented through the callback mechanism.
The following describes representative languages (C, Object Pascal) and Architecture (CORBA) to analyze the implementation method and specific functions of callback.
2. Callback in process language (c)
2.1 function pointer
Callback is implemented by using the function pointer in the C language. The callback is implemented by passing the address of the callback function to the called function. Therefore, to implement callback, you must first define the function pointer. See the following example:
Void func (char * s); // function prototype Void (* pfunc) (char *); // function pointer |
We can see that the definition of a function is very similar to that of a function pointer.
In general, to simplify the definition of variables of the function pointer type and improve the readability of the program, we need to customize the function pointer type.
typedef void(*pcb)(char *); |
A callback function can be called by a program like a normal function, but it can be called a callback function only when it is passed as a parameter to the called function.
Example of the called function:
Void getcallback (PCB callback) { /* Do something */ } When calling the above function, you need to implement a PCB type callback function by yourself: Void fcallback (char * s) { /* Do something */ } Then, you can directly pass fcallback to getcallback as a variable, Getcallback (fcallback ); |
If different values are assigned to this parameter, the caller will call functions of different addresses. Assign values can occur at runtime, so that you can achieve dynamic binding.
2.2 parameter transfer rules
So far, we have only discussed function pointers and callbacks, but have not paid attention to the ansi c/C ++ compiler specifications. Many compilers have several call specifications. For example, in visual
In C ++, you can add _ cdecl, _ stdcall or _ Pascal before the function type to indicate its call specifications (default value: _ cdecl ). C ++
Builder also supports the _ fastcall call specification. The call specification affects the given function name generated by the compiler, the order in which parameters are passed (from right to left or from left to right), and the responsibility for Stack cleanup (caller or
And parameter transfer mechanism (stack, CPU register, etc ).
It is important to regard the call specification as part of the function type. Incompatible call specifications cannot be used to assign addresses to function pointers. For example:
// The called function uses int as the parameter and INT as the return value. _ Stdcall int callee (INT ); // Call a function with the function pointer as the parameter Void caller (_ cdecl int (* PTR) (INT )); // Illegal operation of the called function address in P's Enterprise Image Storage _ Cdecl int (* p) (INT) = callee; // Error |
The pointer P and callee () types are incompatible because they have different call specifications. Therefore, the caller's address cannot be assigned to the pointer P, although the two have the same return value and parameter column.
2.3 Application Example
In many parts of the standard library functions in C language, callback functions are used to allow users to customize the processing process. Such as common quick sorting functions and binary search functions.
Quick Sort function prototype:
Void qsort (void * base, size_t nelem, size_t width, INT (_ userentry * fcmp) (const void *, const void *)); Binary Search function prototype: Void * bsearch (const void * Key, const void * base, size_t nelem, Size_t width, INT (_ userentry * fcmp) (const void *, const void *)); |
Fcmp is a callback function variable.
The following is a specific example:
#include <stdio.h> #include <stdlib.h> int sort_function( const void *a, const void *b); int list[5] = { 54, 21, 11, 67, 22 }; int main(void) { int x; qsort((void *)list, 5, sizeof(list[0]), sort_function); for (x = 0; x < 5; x++) printf("%i/n", list[x]); return 0; } int sort_function( const void *a, const void *b) { return *(int*)a-*(int*)b; } |
2.4 callback in object-oriented language (Delphi)
Like C ++, dephi retains its previous structural features while introducing the object-oriented mechanism to maintain compatibility with Pascal. Therefore, there are two different callback modes: a structured callback mode and an object-oriented interface mode.
2.4.1 callback function
Callback Function Type Definition:
type TCalcFunc=function (a:integer;b:integer):integer; |
Customize the function implementation according to the callback function format, as shown in figure
function Add(a:integer;b:integer):integer begin result:=a+b; end; function Sub(a:integer;b:integer):integer begin result:=a-b; end; |
Use of callback
function Calc(calc:TcalcFunc;a:integer;b:integer):integer |
Next, we can call these two functions in our program as needed.
c:=calc(add,a,b);//c=a+b c:=calc(sub,a,b);//c=a-b |
2.4.2 callback object
What is a callback object? In what scenarios is it used? First, let's compare it with the callback function. The callback function is a prototype that defines the function, and the function body is implemented by a third party.
Application Mode. To implement a callback function, we must know exactly the following points: the parameters required by the function and the type of values returned. Similarly, a callback object is also an object interface defined, but it does not have
The abstract class (that is, the interface) implemented by the object ). To implement a callback object, we must know which methods it needs to implement, which parameters are included in each method, and what values the method needs to return.
Therefore, interfaces are used in the callback object application mode. An interface can be understood as a defined but not implemented class. It can only be implemented by other classes by means of inheritance. Delphi
The interfaces in are similar to those in COM. All interfaces inherit from iinterface (equivalent to iunknow) and must implement three basic methods: QueryInterface,
_ Addref, and _ release.
- Define an Interface
type IShape=interface(IInterface) procedure Draw; end |
- Implementation callback class
type TRect=class(TObject,IShape) protected function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; public procedure Draw; end; type TRound=class(TObject,IShape) protected function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; public procedure Draw; end; |
- Use callback object
procedure MyDraw(shape:IShape); var shape:IShape; begin shape.Draw; end; |
If the input object is trect, draw a rectangle; if it is tround, It is a circle. Users can also implement the ishape interface according to their own intentions to draw their own graphics:
MyDraw(Trect.Create); MyDraw(Tround.Create); |
2.4.3 callback Method
The callback method can be considered as a part of the callback object. Delphi uses the callback method to encapsulate Windows messages. In some cases, we do not need to implement the entire object according to the given requirements, but we only need to implement one of the methods. This is what we will use the callback method.
The callback method is defined as follows:
TNotifyEvent = procedure(Sender: TObject) of object; TMyEvent=procedure(Sender:Tobject;EventId:Integer) of object; |
Tpolicyevent is the most common callback method in Delphi. Many events of forms and controls, such as click events and close events, use tpolicyevent. Variables of the callback method are generally defined by event attributes, such as the definition of the event created by tcustomform:
property OnCreate: TNotifyEvent read FOnCreate write FOnCreate stored IsForm; |
We can customize the event processor by assigning values to the event attribute variable.
User-defined objects (objects containing callback methods ):
type TCallback=Class procedure ClickFunc(sender:TObject); end; procedure Tcallback.ClickFunc(sender:TObject); begin showmessage('the caller is clicked!'); end; |
Form object:
type TCustomFrm=class(TForm) public procedure RegisterClickFunc(cb:procedure(sender:Tobject) of object); end; procedure TcustomFrm..RegisterClickFunc(cb:TNotifyEvent); begin self.OnClick=cb; end; |
Usage:
var frm:TcustomFrm; begin frm:=TcustomFrm.Create(Application); frm.RegisterClickFunc(Tcallback.Create().ClickFunc); end; |
3. Application of callback in distributed computing (CORBA)
3.1 callback interface model
There are many kinds of message transmission mechanisms in CORBA, such as Callback interfaces, event services, and Notification Services. The principle of the callback interface is very simple. both the client and the server have a dual role, that is, acting as a server is also a customer.
The reverse call and forward call of the callback interface are usually performed at the same time. If the server calls the callback interface multiple times, the callback interface becomes an asynchronous interface. Therefore, the callback interface is
This function is often used for event registration. When the client calls this registration function, the client function is a callback function. In subsequent calls, the client does not need to actively participate in this function, this function implements an asynchronous mechanism.
We know from the CORBA specification that a CORBA interface has different forms of representation on the server and the client. The client generally uses the pile (stub) file, and the server uses the framework.
(Skeleton) file, the interface specification is defined by IDL. With the introduction of callback functions, both the server and the client need to implement certain piles and frameworks. The following is the implementation model of the callback interface:
3.1.1 example
The following provides a callback interface file. The server needs to implement the server interface framework, and the client needs to implement the callback framework:
module cb { interface CallBack; interface Server; interface CallBack { void OnEvent(in long Source,in long msg); }; interface Server { long RegisterCB(in CallBack cb); void UnRegisterCB(in long hCb); }; }; |
The client first calls the server interface registcb in synchronous mode to register the callback interface callback. After receiving the request, the server retains the interface reference. If an event needs to be notified to the client, the server uses this reference to call the onevent function of the client, so that the other party can process the request in time.