C Language Reference for Script Programmers - Function Pointers or Callbacks

Function Pointers or Callbacks

Overview                                                                                                                                                                      

A function pointer is a variable that contains the address of a function. Function pointers provide the foundation upon which plugins are built. Without them the process of writing a plugin would be considerably more complex.

Plugins are designed such that they provide user defined functions to the host app to be called when certain events take place. For instance when the user changes the value of one of the interface controls associated with your plugin several events take place. One of these events is that the value has changed (if the control was an edit box it’s contents have changed, if it was a check box it’s state has changed etc.). Another event is that the control needs to be re-drawn to reflect the changes. In both cases a user defined function will be called if one was supplied by the user. This use of function pointers is called a callback, because the host app calls back the user functions.

Syntax                                                                                                                                                                        

When defining a variable as a function pointer you must define it to be a pointer to a function that fits a particular prototype. That is, a function pointer that is defined as taking two ints as arguments cannot point to a function that takes a single float.

So to define a variable called pf that can point to any function that takes two ints as arguments and returns an int we would have:

int  (*pf)(int, int);

Now if you had two functions with the following prototypes:

int  imin(int, int);
int  imax(int, int);

you could assign either of them to pf and call them through pf:

pf = imin;
some_value = pf(2, 5); 

pf = imax;
some_value = pf(4, 8); 

in the first instance pf points to the imin function, therefore imin will be called with the arguments 2 and 5. Then pf is assigned the imax function and called through pf with the arguments 4 and 8. Note that in the case of function pointers you do not need to use the address operator (&), just assign the name of the function.

A common way of using function pointers for plugin communication is the following. The host app will call some known function in any plugin (in the case of a .dll this would be some exported function). The host app will pass to that function a structure that contains a bunch of function pointers. The plugin will then assign it’s own functions to those function pointers and return control to the host app. Now that the host app has pointers to these functions it can freely call them as certain events arise. Here’s a snippet of code that messiah:develop writes out:


mod->CleanUp               = CleanUp;
mod->GetGlobal             = GetGlobal;
mod->AccessNotice          = AccessNotice;
mod->InterfaceCreate       = InterfaceCreate;
… 

This snippet is from the function InitInteract which is the entry point of an edit module. Passed to this function is a pointer to a structure called mod. Some of the members of that structure are function pointers (as indicated above). To these we assign the address of functions that reside in our plugin (actually develop takes care of this for you).

The callbacks that you will deal with most in messiah plugin development are ones associated with access levels. This is how your plugin is made aware of the different events that take place inside of messiah. When you set up your plugin in develop you check off which events you want to be notified of. Develop will create a callback for each of those events, you simply fill in the meat of the callback and you’re all set.

Converted from CHM to HTML with chm2web Pro 2.82 (unicode)