Title: Object-Oriented DLL Interface
Question: Encapsulating a DLL in a nice object is not difficult at all. This chapter explains how.
Answer:
Imagine a DLL with the following published function:
function Test( AStr : string ) : string;
In the following code I will make a type definition of the function and encapsulate it in a object:
{ ---------------------------------------------------------------- }
interface
{ ---------------------------------------------------------------- }
type
// This type is a function with the excact same interface
// as the DLL eqvivalent.
TDLLTest = function( AStr : string ) : string;
// Encapsulated DLL function
TDLLObject = class
private
fDLLTest : TDLLTest; // Handle to DLL Function
fDLLHandle : Thandle; // Handle to DLL
public
constructor Create;
destructor Destroy; override;
function Test( Astr : string ) : string;
end;
{ ---------------------------------------------------------------- }
implementation
{ ---------------------------------------------------------------- }
constructor TDLLTest.Create;
begin
// This function will assign the dll to my handle:
// Replace the MYDLL.DLL with the name of your DLL
fDLLHandle := LoadLibrary( 'MYDLL.DLL' );
// Handle error if DLL could not be loaded
if fDLLHandle raise Exception.CreateFmt( 'DLL not found. Error: %s',
[GetLastError] );
// Assign DLL function to function handle.
// The parameter 'test' is the name of the DLL function
// I wish to assign
fDLLTest := GetProcAddress( fDLLHandle, 'TEST' );
// Handle error if interface not found
if fDLLTest = nil then
raise Exception.CreateFmt( 'Procedure TEST not found. ' +
'Error: %s',
[GetLastError] );
// At this point the DLL should be loaded and ready for use
end;
{ ---------------------------------------------------------------- }
function TDLLTest.Test( AStr : string ) : string;
begin
// This function returns the value of DLL function
// TEST.
result := fDLLTest( AStr );
end;
{ ---------------------------------------------------------------- }
destructor TDLLTest.Destroy;
begin
// Always remember to free your DLL on exit
if fDLLHandle 0 then
FreeLibrary( fDLLHandle );
end;
A Word On DLLs
You should never let your DLL's return Delphi strings. Returning Delphi strings (type String and WideString) can only be done with help from Delphis memory manager DLL which is not always present on your target machine (unless you distribute it with your application).
Instead, use pointers and the type pChar to pass strings.
With this approach, you also ensure that your DLL can be used by other programming languages, like C++.