打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
call a DLL function with variable RT-parameter dynamically?
call a DLL function with variable RT-parameter dynamically?
Author:Thomas Weidenmueller
Homepage: http://www.w3seek.us
[ Print tip ]    

Tip Rating (13):  
 
 
 
 
 



(*
--- english -------------------------------------------------------------------
These two functions allow to dynamically call DLL functions with dynamically
customizable parameters.
Also allow a programm to call a function with at design time unknown parameters
(you'll have to implement the dynamicall filling of the array of pointer).
--- german --------------------------------------------------------------------
Mit diesen Funktionen k?nnen Sie dynamische Aufrufe von DLL-Funktionen
realisieren.
Sie legen zur Laufzeit den Namen der Funktion und bestimmen ebenso welche
Parameter übergeben werden sollen und von welchem Typ diese sind (zu
Letzteres kann eine entsprechende Prozedur geschrieben werden).
*)

// Calls a function from a library.
// if it's not loaded yet, it will call LoadLibrary() to load it.
function DynamicDllCallName(Dll: Stringconst Name: String; HasResult: Boolean; var Returned: Cardinal; const Parameters: array of Pointer): Boolean;
var
  
prc: Pointer;
  x, n: Integer;
  p: Pointer;
  dllh: THandle;
begin
  
dllh := GetModuleHandle(PChar(Dll));
  if dllh = 0 then begin
    
dllh := LoadLibrary(PChar(Dll));
  end;
  if dllh <> 0 then begin
    
prc := GetProcAddress(dllh, PChar(Name));
    if Assigned(prc) then begin
      
n := High(Parameters);
      if n > -1 then begin
        
x := n;
        repeat
          
p := Parameters[x];
          asm
            
PUSH p
          end;
          Dec(x);
        until x = -1;
      end;
      asm
        
CALL prc
      end;
      if HasResult then begin
        asm
          
MOV p, EAX
        end;
        Returned := Cardinal(p);
      end else begin
        
Returned := 0;
      end;
    end else begin
      
Returned := 0;
    end;
    Result := Assigned(prc);
  end else begin
    
Result := false;
  end;
end;

// Calls a function from a loaded library
function DynamicDllCall(hDll: THandle; const Name: String; HasResult: Boolean; var Returned: Cardinal; const Parameters: array of Pointer): Boolean;
var
  
prc: Pointer;
  x, n: Integer;
  p: Pointer;
begin
  
prc := GetProcAddress(hDll, PChar(Name));
  if Assigned(prc) then begin
    
n := High(Parameters);
    if n > -1 then begin
      
x := n;
      repeat
        
p := Parameters[x];
        asm
          
PUSH p
        end;
        Dec(x);
      until x = -1;
    end;
    asm
      
CALL prc
    end;
    if HasResult then begin
      asm
        
MOV p, EAX
      end;
      Returned := Cardinal(p);
    end else begin
      
Returned := 0;
    end;
  end else begin
    
Returned := 0;
  end;
  Result := Assigned(prc);
end;


(* --------- Sample (GetSystemDirectory) --------- *)

var
  
parameters: array of Pointer;
  returned: Cardinal;
  Dir: String;
begin
  
SetLength(parameters, 2);
  SetLength(Dir, MAX_PATH); // Set Buffer size
  
parameters[0] := Pointer(@Dir[1]); // 1st parameter, buffer for path string
  
parameters[1] := Pointer(MAX_PATH); // 2nd parameter, length of buffer
  
if not DynamicDllCallName(kernel32, 'GetSystemDirectoryA', true, returned, parameters) then begin
    
ShowMessage('Function could not be found!');
  end else begin
    
SetLength(Dir, returned); // Cut String
    
ShowMessage('GetSystemDirectoryA:'#13#10'Path: ' + Dir + #13#10'Length: ' + IntToStr(returned));
  end;
end;


(* --------- Sample (TextOut) --------- *)

const
  
SampleText = 'test';
var
  
parameters: array of Pointer;
  returned: Cardinal;
begin
  
SetLength(parameters, 5);
  parameters[0] := Pointer(Canvas.Handle); // 1st parameter, handle to the form's canvas
  
parameters[1] := Pointer(10); // 2nd parameter, left margin
  
parameters[2] := Pointer(30); // 3rd parameter, top margin
  
parameters[3] := @SampleText[1]; // 4th parameter, pointer to the sample string
  
parameters[4] := Pointer(Length(SampleText)); // 5th parameter, length of the sample string
  
if not DynamicDllCallName(gdi32, 'TextOutA', true, returned, parameters) then begin
    
ShowMessage('Function could not be found!');
  end else begin
    if not 
BOOL(returned) then begin // function's result = false
      
ShowMessage('TextOut() failed!');
    end;
  end;
end;


(* --------- Sample (LockWorkStation) --------- *)

var
  
parameters: array of Pointer;
  returned: Cardinal;
begin
  
// We don't have parameters, so we don't touch parameters
  
if not DynamicDllCallName(user32, 'LockWorkStation', true, returned, parameters) then begin
    
ShowMessage('Function could not be found!');
  end else begin
    if not 
BOOL(returned) then begin
      
ShowMessage('LockWorkStation() failed!');
    end;
  end;
end;

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Delphi的"Invalid pointer operation"异常的解决办法 - D...
delphi 取得任意程序的命令行
服务器开发
delphi版inf方式加载驱动
PING
Delphi 选择文件夹对话框 (有新建文件夹按钮)修正版
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服