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
TFunctionLoader = class
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;
function LoadFunction(const LibraryName, FunctionName: string;
out FunctionPointer: Pointer): Boolean;
end;
{ TFunctionLoader }
constructor TFunctionLoader.Create;
begin
FLibraries := TStringList.Create;
FFunctions := TStringList.Create;
end;
destructor TFunctionLoader.Destroy;
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;
function TFunctionLoader.LoadFunction(const LibraryName, FunctionName: string;
out FunctionPointer: Pointer): Boolean;
var
i: Integer;
LibraryHandle: THandle;
begin
i := FFunctions.IndexOf(FunctionName); // Is the function already loaded?
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
LibraryHandle := Windows.LoadLibrary(PChar(LibraryName));
if LibraryHandle = 0 then Exit(False); // Failed, quit
i := FLibraries.AddObject(LibraryName, TObject(LibraryHandle));
end;
// Load the function from the library
FunctionPointer := Windows.GetProcAddress(THandle(FLibraries.Objects[i]),
PChar(FunctionName));
Result := Assigned(FunctionPointer); // succeeded?
if Result then // Add the function to FFunctions
FFunctions.AddObject(FunctionName, TObject(FunctionPointer));
end;
With above you can define var FunctionLoader: TFunctionLoader; somewhere and add this to the end of the unit
initialization
FunctionLoader := TFunctionLoader.Create;
finalization
FunctionLoader.Free;
end.
Use it as
Result := FunctionLoader.LoadFunction('User32.dll', 'BlockInput', @BlockInput)
and BlockInput(not Enable);
All functions and libraries will be loaded only once and will be automatically freed.