I am trying to write a generic function for loading a function from a DLL library. I am in no way an expert on DLLs, that is why I ask.

We have discussed it first in my Stack Overflow question to discover the most obvious errors, and there were some crucial ones.

Current version of my code follows:

function LoadFunctionFromLibrary(const LibraryName, FunctionName: string; out FunctionPointer: Pointer): Boolean;

var
LibraryHandle: THandle;

begin
Result := False;
FunctionPointer := nil;

if LibraryHandle = 0 then Exit;

if Assigned(FunctionPointer) then
Result := True;
end;


This version of the function has been successfully tested on my EnableInput function:

function EnableInput(const Enable: Boolean): Boolean;

var
BlockInput: function(Block: BOOL): BOOL; stdcall;

begin
Result := LoadFunctionFromLibrary('User32.dll', 'BlockInput', @BlockInput) and
BlockInput(not Enable);
end;


Just like Dangph, I wonder why you need this. There are other better approaches suggested in the previous comments.

Even if this is useful, Your solution is not great: 1. You repeatedly load the library and the function. 2. There is no way for you to free the loaded libraries.

Here is a better way to do it:

type
private
FLibraries: TStrings;   // This stores the library handles and names
FFunctions: TStrings;   // This stores the function pointers and names
public
constructor Create;
destructor Destroy; override;
out FunctionPointer: Pointer): Boolean;
end;

begin
FLibraries := TStringList.Create;
FFunctions := TStringList.Create;
end;

var
i: Integer;
begin
for i := 0 to FLibraries.Count - 1 do     // free all opened libraries
Windows.FreeLibrary(THandle(FLibraries.Objects[i]));
FLibraries.Free;                          // free other objects
FFunctions.Free;
end;

out FunctionPointer: Pointer): Boolean;
var
i: Integer;
LibraryHandle: THandle;
begin
if i >= 0 then
begin                                     // Yes, just return the stored pointer
FunctionPointer := Pointer(FFunctions.Objects[i]);
Exit(True);
end;

i := FLibraries.IndexOf(LibraryName);     // No, test if the library is already loaded
if i < 0 then
begin                                     // No, load it and store in FLibraries
if LibraryHandle = 0 then Exit(False);  // Failed, quit
end;

// Load the function from the library
PChar(FunctionName));
Result := Assigned(FunctionPointer);      // succeeded?
if Result then                            // Add the function to FFunctions
end;


With above you can define var FunctionLoader: TFunctionLoader; somewhere and add this to the end of the unit

initialization

Result := FunctionLoader.LoadFunction('User32.dll', 'BlockInput', @BlockInput)