About the callback function

xiaoxiao2021-03-18  188

First, callback function

We often make some applications (such as timer event callback processing, recording actions with callback functions, etc.) when designing the callback function, so that its inner mechanism is, how is it defined? ? Is it different from other functions (such as hook functions)?

Using the callback function is actually when a function is called (usually an API function), the address of one of its functions (this function is a callback function) is passed to that function.

And that function is required to call the callback function using the delivered address, then you can use this opportunity to process messages in the callback function or complete a certain action. As for how to define the callback function, it is related to the specific API function, generally in the help, the parameters and return values ​​of the callback function. C generally requires Callback before the callback function, which is mainly to explain the call mode of the function.

As for the hook function, just a special case of the callback function. It is used to refer to the callback function used with the setWindowsHooKex function as the hook function. Some people use the function that uses the VirtualQueryEx installed as hook functions, but this called is not popular.

It can also be more likely to understand that the callback function is like an interrupt processing function, and the system is automatically called when it meets the conditions you set. To this end, you need to do three things:

Declaration;

2. Definition;

3. Set the trigger condition, which is transformed into the address as a parameter in your function to make the system call.

Note and definition should pay attention to: The callback function is called by the system, so it can be considered to be a Windows system, do not treat it as a member of your class.

Second, the callback function, message and event routine

The calling mechanism has been used in a lot of use from the assembly era: preparing an outgoing code, and the caller can jump to the start address of this code, and then return the subsequent address when the jump is returned. The CPU prepares ready-made call instructions for this purpose. When calling the site, the field address is played from the stack after the call is completed to automatically return. The stack protection site is a wonderful invention, which makes the caller and the adjuster without each other, so there is a later function and component.

This call mechanism is not perfect. The callback function is an example. The function and other meals prepared for the caller, and its cooking deals with diners, but the truth is not the case. For example, write a quick sort function for others to call, which must contain a relatively small. Trouble coming: What data-integer, floating point, string? Thus, there is only a different sort function for each type of data. More password is to column a callback function address in the function parameters, and notify the caller: Jun must prepare a comparison function, which contain two pointer parameters, the function should compare the size of this two pointer index, and by Function Return Value Description Comparison Results. The sort function is relatively small, and the parameters are passed by the pointer, and the comparative data type can be fully compared. The caller is turned back to call the caller's function (sufficient bite), so it is called a callback.

The callback function makes the program structure a lot. There are many callback functions in the Windows API function. Although there is a detailed description, the beginners still make the beginners fog. I am afraid this is also helpless.

No matter what kind of things, it can be comfortable with the tree structure single-way description. If a grandchildren in a family is a ancest, I am afraid that no one can clarify the clue. But the complex data processing often needs to form a mesh structure, and non-simple client / server relationships can be exhausted. The Windows system also contains another more wide callback mechanism, namely a message mechanism. The message is the basic control means of Windows, and the watch is not related to the function call, it is actually a variable function call. The purpose of sending messages is to inform the recruitment to run a preparatory code, which is equivalent to calling a function. The WPARAM and LPARAM included with the message are equivalent to the parameters of the function, but more common than normal parameters. The application can actively send messages, more cases, waiting for Windows send messages. Once the message enters the message queue, those who are interested, jump to perform the corresponding message processing code. The operating system is called the application service, called by the application. Once the application is started, it will be in turn to wait for the call to the operating system. This is also a callback, or is a generalized callback. In fact, this callback can also be formed between the applications. If the process B receives the message sent by the process A, it starts a piece of code, which sends a message to the process A, which forms a callback. This kind of callback is more concealed, and it will not be able to recurrently call. If you deliberately write this recursive call, it is very interesting to terminate the conditions. But this program structure is too hidden unless it is necessary, it is still not necessary.

Using messages can also be constituted a narrow callback. An example of the above-mentioned sorting function can be replaced with the callback function address to the window handle. Thus, when comparing data is required, the callback function is not called, but transmits a message to the specified window by using the API function sendMessage. Receiving the message party is responsible for comparing the data size, transmitting the comparison result to the message sender through the return value of the message itself. The functionality implemented is not different from the callback function. Of course, this example is changed to the news purely seduce snake to fate, but the program is very slow. But in other cases, it is not always, especially when you need asynchronous calls, the send message is a nice choice. If the callback function contains low-speed processing, the caller, etc., the caller is not allowed to change the synchronization call to asynchronous calls, start a separate thread, then immediately perform subsequent code, and the rest will make the thread slowly do it. An alternative is to send an asynchronous message by the API function PostMessage, and then perform subsequent code immediately. This is much better than yourself, and safer.

Now we are living in an Object era. As long as you are related to programming, no matter what happens, you can ink Object. However, Object did not eliminate callbacks, but in turn, it has all, it is, but most of them appear in an event (Event), inlaid in a certain structure, which is more intended to be accepted. The application uses a component, always draw the properties, methods, and events of the component, and then assign the component attribute, call the appropriate component method when appropriate, and write the handup routine for the event to prepare component code. Call. What is the event? It is just a address that points to the event routine, and there is no difference with the callback function address.

However, this callback is much better than traditional callback functions. First, it turns a very uncomfortable callback function into a natural handling routine that makes the programmer feel smooth. Furthermore, the address is a dangerous thing, using it to accelerate the procedure, use a nothing to be a trap, and the program will crash at any time. Modern programming methods always think about hide the address (hidden than VB and Java), which costs the program efficiency. The event routine (?) Makes the programmer do not need to act directly, but does not decelerate the program. (The routine seems to be the process of Taiwan translation.) Third, the exquisite metaphor: the callback function is really like the BP machine you belled: Tell someone to numbers, Call when there is something.

The callback is used in the interlayer collaboration. The upper layer is installed in the lower layer. This function is a callback, and the lower layer triggers a callback under certain conditions, such as a driver, is a bottom layer, when he receives a data, in addition to completing this In addition to the processing of the layer, it will also be called to give this data to the upper application layer for further processing, which is common in the hierarchical data communication. In fact, the callback and API are very close, and their commonality is a function of cross-layer calls. But the difference is that the API is a low-level call. Generally, this function is known to the high level; the callback is just the opposite, he is a high-level call, for the low level, he is unknown, must be installed by the high level, This installation function is actually a low-level API. After installation, the low level does not know the name of this callback, but it saves this callback through a function pointer, and simply reference this function pointer and related parameter pointer. In fact: The callback is the function written on the high-level, and the low layer saves this function through a function pointer. Under the trigger of an event, the low layer calls the high layer function by the function pointer.

There is always a certain interface between the four software modules. From the call mode, they can be divided into three categories: synchronous call, callback, and asynchronous calls. Synchronous call is a blocking call, the call party must wait for the other party to return, it is a one-way call; the callback is a two-way call mode, that is, the called party is called when the interface is called. The other party's interface; asynchronous calls are a mechanism for similar messages or events, but its calling direction is just in contrast, and the interface is actively informing the client when receiving a message or something happens. Interface). The relationship between the callback and asynchronous calls is very close, usually we use the callback to realize the registration of asynchronous messages, and notifications of messages through asynchronous calls. Synchronous calls are the simplest in all three, and callbacks are often the basis for asynchronous calls. For different types of languages ​​(such as structural language and object language), platform (Win32, JDK), or Corba, DCOM, WebService, customer and service, in addition to synchronization, there is a certain asynchronous notification mechanism, Let the service party (or interface provider) can actively inform the customer in some cases, while the callback is a simplest way to achieve asynchronous.

For a general structured language, callback can be achieved by callback function. The callback function is also a function or process, but it is a special function that is implemented by the calling party for use by the caller.

In the object-oriented language, the callback is implemented by an interface or abstract class. We make the class that implements this interface into a callback class, and the callback class is a callback object. For object languages ​​that are compatible with C or Object Pascal, it is also provided with the characteristics of the callback object, the callback method, but also compatible with the callback function mechanism of the process language. The message mechanism of the Windows platform can also be regarded as an application of the callback, and we register the message processing function (ie the callback function) through the system provided, so that the purpose of receiving, processing the message. Since the API of the Windows platform is built with C language, we can think it is also a special case of the callback function.

For distributed component agent CORBA, there are various ways, such as callback, event service, notification service, etc. Event service and notification services are standard services for CORBA to handle asynchronous messages, and they are responsible for the processing, distribution, maintenance of messages. For some simple asynchronous processing, we can be implemented by a callback mechanism.

Below we focus on comparing representative language (C, Object Pascal) and architecture (CORBA) to analyze the implementation of the callback, the specific functions.

2 Power in the process language (c)

2.1 Function Pointer Pressure is implemented by a function pointer in a C language. By transmitting the address of the callback function to the modulated function to achieve the callback. Therefore, to achieve a callback, you must first define a function pointer, please see the example below:

Void func (char * s); // Function prototype VOID (* pfunc) (char *); // function pointer

It can be seen that the definition of the function is very similar to the definition of the function pointer.

Generalization, in order to simplify the variable definition of the function pointer type, improve the readability of the program, we need to customize the function pointer type.

TypeDef void (* pcb) (char *);

The callback function can be called like a normal function, but only it is called a callback function when it is passed as a parameter to the called function.

Example of the modulous function:

Void getCallback (PCB Callback) {/ * do Something * /} User When calling the above function, you need to implement a PCB type callback function: void fcallback (char * s) {/ * do something * /} then, You can pass the FCallback directly as a variable to getCallback, getCallback (fcallback);

If the different values ​​are assigned to this parameter, the caller will call a function of different addresses. The assignment can occur when running, so that you can realize dynamic binding.

2.2 Parameter Transfer Rules So far, we only discuss the function pointer and callback without paying attention to the compiler specification of ANSI C / C . Many compilers have several invoking specifications. For example, in Visual C , you can add _cDecl, _stdcall, or _pascal in front of the function type, indicate its call specification (default to _cDecl). C Builder also supports _fastcall call specification. Call specification affects the given function name generated by the compiler (from right to left or from left to right), stack cleaning responsibility (caller or called by caller) and parameter transfer mechanism (stack, CPU register, etc.) .

It is important to see that the call specification is part of the function type; the address cannot be assigned to the function pointer with an incompatible call specification. E.g:

// The modified function is an int called a parameter, with INT to return value __stdcall int callee (// call function with function pointer as parameter Void Caller; "

// In Phase P, I illegally operated illegal operation __cdecl int (* p) (int) = callee; // error

The types of pointers P and Callee () are not compatible because they have different call specifications. Therefore, it is not possible to assign the address of the caller to the pointer P, although the two have the same return value and the parameter column.

2.3 Application Examples The standard library function in the C language uses a callback function to let the user customize the process. Such as common rapid sort functions, secondary search functions, etc.

Quick Sort Function Prototype:

Void Qsort (Void * Base, Size_t Nlem, Size_t Width, INT (_USERENTRY * FCMP) (const void *, const void *); two-point search function prototype: void * bsearch (const void * key, const void * base, size_t NELEM, SIZE_T WIDTH, INT (_USERENTRY * FCMP) (const void *, const void *);

Where FCMP is a variable of a callback function.

A specific example is given below:

#I nclude #i nclude

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 Tune in object-oriented language (Delphi)

DEPHI is the same as C , in order to maintain compatibility with process language, it retains previous structured characteristics while introducing an object-oriented mechanism. Therefore, there are two distinct modes of the callback, one is a structured function callback mode, one is an object-oriented interface mode.

转载请注明原文地址:https://www.9cbs.com/read-129947.html

New Post(0)