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