2005. december 24., szombat

Callback function with a DLL

Problem/Question/Abstract:

How to make a DLL like a controller and how to write a callback-function with a DLL

Answer:

Callback function with a DLL

First a brief definition: A callback function is a function which you write, but is called by some other program or module, such as windows or DLL's.
For example a DLL (like a watchdog) controls many clients, so when a certain event occurs from the DLL that you called once, the callback function in the client is called (being passed any parameters or signals you need) and when the DLL-callback has completed, control is passed back to the controller-DLL or the client.

By the way, there is almost no possibilitie to make it more OO-like with a class, cause a callback is always an address of a standard procedure or function.
So the reason for this is that windows does not pass back any reference to SELF (means the instance of the class), which is used by classes when deciding which method from the instance to work with.

Let's get back to the framework and create a callback function, you must first:

declare a function type
the function itself
define the DLL reference
then implement the function in the client
and call the DLL:

Callback example in client unit

1.
interface...
TCallBackFunction = function(sig: integer): boolean;

2.
function callME(sig: integer): boolean;

3.
implement...

procedure TestCallBack(myCBFunction: TCallBackFunction); register;
external('watchcom.dll');

4.
function callMe(sig: integer): boolean;
begin
{whatever you need to do, case of...}
showmessage('I was called with' + inttostr(sig));
end;

5.
procedure TForm1.Button1Click(sender: TObject);
begin
testCallBack(callMe); //subscribe function in DLL
end;

Callback in the DLL

In the DLL you would also declare a function type and a procedure (or function) itself, so use it like this:

type
TCallBackFunction = function(sig: integer): boolean;

procedure TestCallBack(clientFunc: TCallBackFunction);
var
sigAlive: boolean;
begin
{timer stuff...
set the signal...}
if (clientFunc(55)) then
sigalive := true;
end;

exports TestCallBack;

Simple Sequence Diagram

Client                                           DLL
¦ TestCallBack(clientFunc) ¦
¦---------------------------------------------->¦
¦ clientFunc.callMe(sig) ¦
&brvbar;<----------------------------------------------&brvbar;
&brvbar; true (or something to return)           &brvbar;
&brvbar;---------------------------------------------->&brvbar;



Nincsenek megjegyzések:

Megjegyzés küldése