Forum > Packages and Libraries

Using dll within class

(1/1)

DelphiDinosaur:
I have a class that is created when my program starts, and is free'd when it closes. It accesses functionality within a dll by dynamically loading the dll functions via LoadLibrary. It is possible/wise to have the dll accessed by class variables rather than within each function?

Simplified examples follow, my actual code has extra type conversions needed to access the dll (strings <->pchar etc) and accesses several routines within the dll (all working and irrelevant to the question):

Shared header:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---const    DLL_NAME = 'Adder.dll';type    TAdd = function(A: byte; B: byte): word; cdecl; 
Example A:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---typeTExample_A = classprivate    dllHandle: LongWord;    fnAdd: TAdd;public    constructor Create;    destructor Destroy;    function Add(A: byte; B: byte): word;end; implementation constructor TExample_A.Create;begin    dllHandle := LoadLibrary(PChar(DLL_NAME ));    if (dllHandle <> 0) then        Pointer(fnAdd) :=GetProcAddress(dllHandle, 'Add');end; destructor TExample_A.Destroy;begin    FreeLibrary(dllHandle);end; function TExample_A.Add(A: byte; B: byte): word;begin    if Assigned(fnAdd) then        Result := fnAdd(A, B)    else        Result := 0;end; 
Example B:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---typeTExample_B = classpublic    function Add(A: byte; B: byte): word;end; implementation function TExample_B.Add(A: byte; B: byte): word;var    dllHandle: LongWord;    fnAdd: TAdd;begin    Result := 0;    dllHandle := LoadLibrary(PChar(DLL_NAME ));    if (dllHandle <> 0) then    begin        Pointer(fnAdd) :=GetProcAddress(dllHandle, 'Add');        if Assigned(fnAdd) then            Result := fnAdd(A, B);        FreeLibrary(dllHandle);    end;    end; 
Is TExample_A a valid method of dealing with dlls?

I appreciate TExample_B is more robust should the dll be removed during run-time, but does TExample_A reduce the number of times the dll is loaded? My guess is that TExample_A loads the function into memory and then no longer access the dll file whilst the class is in existance.

Would I be better off using statically linked functions?

--- Code: ---type
function Adder(A: byte; B: byte): word; cdecl; external 'Adder.dll' name 'Add';

TExample_C = class
public
    function Add(A: byte; B: byte): word;
end;

implementation

function TExample_C.Add(A: byte; B: byte): word;
begin
    try
        Result := Adder(A, B);
    except
        Result := 0;
    end;
end;


--- End code ---

If so, what's the best way of coping with the eventuality that the dll isn't installed/registered?

DD.

Zvoni:

--- Quote from: DelphiDinosaur on May 11, 2023, 01:16:31 pm ---
If so, what's the best way of coping with the eventuality that the dll isn't installed/registered?

DD.

--- End quote ---
IMO, Dynamic loading.
Put a FileExists('MyDll.dll') before the LoadLibrary-call.
It's a simple boolean-condition

Aircode!

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---If FileExists('MyDLL.dll') Then  //or full relative/absolute path    //Do your LoadLibrary and Assign Function-Pointer-StuffElse   ShowMessage('Oooops!'); 

DelphiDinosaur:

--- Quote from: Zvoni on May 11, 2023, 01:34:13 pm ---Put a FileExists('MyDll.dll') before the LoadLibrary-call.
It's a simple boolean-condition

--- End quote ---

This only works if the dll is in a known location. If it's been installed to a random folder and registered via RegSvr32 the LoadLibrary() function will find it but FileExists() won't unless the exact path is specified.

DD.

rvk:

--- Quote from: DelphiDinosaur on May 11, 2023, 01:16:31 pm ---I appreciate TExample_B is more robust should the dll be removed during run-time, but does TExample_A reduce the number of times the dll is loaded? My guess is that TExample_A loads the function into memory and then no longer access the dll file whilst the class is in existance.
--- End quote ---
No, when you do LoadLibrary, the dll can't be removed (until the call to FreeLibrary).
And even if it shows as removed on a server, it might not actually be removed (only removed from view) until the dll is released.

All shown methods are valid (static/non static, load per call, load per class). It depends on your preference and use-case what you will choose.

I would only use example B (loading the dll per function call and releasing it directly) when you don't call that function too often.

Zvoni:

--- Quote from: DelphiDinosaur on May 11, 2023, 03:20:28 pm ---
--- Quote from: Zvoni on May 11, 2023, 01:34:13 pm ---Put a FileExists('MyDll.dll') before the LoadLibrary-call.
It's a simple boolean-condition

--- End quote ---

This only works if the dll is in a known location. If it's been installed to a random folder and registered via RegSvr32 the LoadLibrary() function will find it but FileExists() won't unless the exact path is specified.

DD.

--- End quote ---
You did see my comment in that codeline regarding relative/absolute path?

Navigation

[0] Message Index

Go to full version