Delphi中动态调用dll的方法如下
1 function GTPEnviormentState(aa:string): WideString; 2 const 3 dllName = 'Test.dll'; 4 funName = 'EnviormentState'; 5 var 6 dllHandle: THandle; 7 fullDllName: WideString; 8 func: function(url: WideString): LPWSTR; stdcall; //每个函数不一样 9 addr:pchar; 10 11 begin 12 try 13 fullDllName := TGTPPath.GetToolsWorkSpaceDir + '\' + dllName; 14 dllHandle := LoadLibraryW(PWideChar(fullDllName)); 15 try 16 if dllHandle <> 0 then 17 begin 18 @func := GetProcAddress(dllHandle, funName); 19 if Assigned(func) then 20 begin 21 // Result := func(strJson); 22 end 23 else Result := ''; 24 end 25 else Result := ''; 26 finally 27 FreeLibrary(dllHandle); 28 end; 29 except on E: Exception do 30 begin 31 Result := ''; 32 33 end; 34 end; 35 end;
这个函数没有问题,可以正常执行。
但是如果我有很多函数都需要动态调用,就需要把上面的方法复制很多遍。但其实只有很少一部分变动,其他都是固定的
func: function(url: WideString): LPWSTR; stdcall; //每个函数不一样
有什么办法把这个方法抽象出来? 变的部分当作参数传进去 ?
函数的返回值,参数都有可能不相同。 最好不要污染全局变量, 本人刚刚接触Delphi,非常感谢
网上搜到答案了,测试通过。不过我测试了一下静态和动态调用的性能,相差一个数量级左右
代码
function CallFunc(dllname, funcname: string; const param: array of const): DWORD; var hLib: THandle; pFunc: Pointer; intSize: Integer; begin Result := 0; hLib := LoadLibrary(PChar(dllname)); if hLib <> 0 then begin pFunc := GetProcAddress(hLib, PChar(funcname)); if pFunc <> nil then begin // 获取参数大小 intSize := Length(param); // 以下汇编码将自动完成函数调用 asm push ecx push esi mov ecx, intSize; // 参数的个数 mov esi, param test ecx, ecx // 判断是否有参数 je @call // 如果没有参数则跳转到函数调用处 @again: dec ecx push dword ptr [esi + ecx * 8] // 循环把参数压入堆栈 cmp ecx, 0 jnz @again // 一直循环到 ecx 为0 @call: call pFunc // 调用函数 mov @Result, eax // 返回值 pop esi pop ecx end; end; FreeLibrary(hLib); end; end;
然后调用的时候如下:
CallFunc('user32.dll', 'MessageBoxA', [0, 'hello world', 'title', MB_OK]);
CallFunc('user32.dll', 'MessageBeep', []);
CallFunc('kernel32.dll', 'Sleep', [1000]);
delphi问题你最好到大富翁论坛上问,这儿大部价屌丝,呵呵。
VOID * pFunctionPointer = GetFunctionPointer(funName);
@func = (function(url: WideString): LPWSTR; stdcall) pFunctionPointer;
没有搞明白,请明示,谢谢
@卒子:
function GetFunctionPointer(aa:string): Pointer;
func1: function(url: WideString): LPWSTR; stdcall; //每个函数不一样
func2: function(url: WideString): LPWSTR; stdcall; //每个函数不一样
func1 = GetFunctionPointer("EnviormentState1");
func2 = GetFunctionPointer("EnviormentState2");