I am trying to figure out how to call a procedure in an application from a DLL (not how to call a procedure in the DLL). Both the application and the DLL are developed with Delphi 11.
procedure DrawRectangle( X, Y, W, H: Integer );
var
MyRect: TRectangle;
begin
MyRect := TRectangle.Create( mainForm );
//and so on...
end;
DrawRectangle( 10, 10, 100, 100 );
Any help with a simple example would be very much appreciated. I have searched and read several articles online and still cannot get a grasp of how to accomplish what I am trying to do.
That's just like setting a callback in general. Just combine writing a DLL with defining procedural types:
library Lib;
type
// The callback must be defined type as procedure or function,
// so the compiler knows all parameters and the calling convention.
// The name is only relevant to the type, not the procedure.
TProcDrawRectangle= procedure( X, Y, W, H: Integer ); stdcall;
var
// The pointer which either got something assigned to call or not.
ProcToCall: TProcDrawRectangle= nil;
// We call this to pass (the pointer to a) procedure which this DLL
// can later call on its own to execute the procedure elsewhere.
procedure LinkMyCallback( proc: TProcDrawRectangle ); stdcall;
begin
ProcToCall:= proc;
end;
// However, when/where the callback is executed is up to you.
procedure OtherThings(); stdcall;
begin
//...
if Assigned( ProcToCall ) then ProcToCall( 10, 20, 800, 600 );
end;
exports
LinkMyCallback,
OtherThings;
begin
end.
Now do the same in your program, along with importing the DLL's procedures:
program Main;
type
// The same definition as in the library, of course. Naturally you would put this
// once in a unit, which is then used by both: your program and the DLL.
TProcDrawRectangle= procedure( X, Y, W, H: Integer ); stdcall;
// Statically linking the procedure (or functions) which are exported by the library.
procedure LinkMyCallback( proc: TProcDrawRectangle ); stdcall; external 'Lib.dll';
procedure OtherThings(); stdcall; external 'Lib.dll';
// Will be called from the library.
procedure CallbackHere( X, Y, W, H: Integer ); stdcall;
begin
//DrawRectangle( X, Y, W, H: Integer );
end;
begin
// Hand over (a pointer to) the procedure which it wants to call
// at a later time.
LinkMyCallback( CallbackHere );
// Now is a "later time": executing this library's procedure will in
// turn call on the DLL side the procedure pointer, which is then
// executing "CallbackHere()" in this program.
OtherThings();
end.
Keep an eye on making all exported procedures/functions using the same calling convention - Delphi works best with stdcall
. Avoid using Delphi-only types like String
or classes/objects in general - better use simple types and helper functions to indirectly operate with objects. Do's and don'ts when working with DLLs is a different topic.