关于dll 动态调用

Jack_Yin 2008-09-27 04:05:27
一个动态调用DLL的 菜鸟问题:

假如我在dll中有个函数function Max(X, Y: Integer): Integer; stdcall;

然后在主程序中动态调用这个dll,
开始是要myhandle := loadlibrary('*.dll')
然后就要用GetProcAddress得到函数的地址.
如果将这个地址赋值给一个变量,这个变量的类型是不是必须要 type 成
TGetMax = function (x:integer;y:integer): integer;stdcall; (就是要跟dll中申明的完全一样)
然后再var myfunc:TGetMax;
myfun := GetProcAddress(myhandle,'Max');

有没有一种通用变量,来保存GetProcAddress返回的值能?我在一些资料上看过 TFarProc类型,可是在delphi帮助中却没有看到,
这个问题甚是迷惑,请各位高手赐教.

另外 就是给这个变量赋值问题
有的这么写的:
@myfun := GetProcAddress(DLLHandle, 'Min');
if Assigned(@myfun) then
begin
D := myfun(2,3);
showmessage(inttostr(d));
end;

还有一种是
myfun := GetProcAddress(DLLHandle, 'Min');
D := myfun(2,3);

这两种写法有什么区别,是否都正确?@,Assigned是什么意思?
谢谢先!!


...全文
131 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jack_Yin 2008-10-01
  • 打赏
  • 举报
回复
太感谢了,马上结帖给分
iamduo 2008-09-28
  • 打赏
  • 举报
回复
Assigned就是判断是否为nil
@myfun表示的是myfun变量的地址
GetProcAddress按字面意思就可以知道,是指返回过程的地址。(如果找不到,返回nil)
if Assigned(@myfun) then 也就是if @myfun<>nil then 两者一个意思。
但是,前者显得"高级"一点,让lz这样初次碰到的时候感觉茫然。
个人认为,使用第一种比较好,万一,你把dll中改掉了,那么就会出现报地址错误,不好看了。
jacknes009 2008-09-28
  • 打赏
  • 举报
回复
GetProcAddress函数返回的一个地址
我想如果楼主懂指针的话,上面的问题应该不难理解

~~~
liangpei2008 2008-09-27
  • 打赏
  • 举报
回复
向刀友兄学习
lihuasoft 2008-09-27
  • 打赏
  • 举报
回复

4楼那段汇编码,可以再精简一下:


asm
mov edi, Para
mov edx, [edi]-4
@AGAIN:
mov eax, [edi]+edx*4-4
push eax
dec edx
cmp edx, 0
jnz @AGAIN{比较不为零直接使用jnz跳转循环}
call F
mov Rst, eax
end;
lihuasoft 2008-09-27
  • 打赏
  • 举报
回复
关于楼主提出的第二个问题,附议三楼,另外我想只要看看下面的代码就明白了:


type
TFunc = function (v1,v2: integer): integer;

function XX(v1,v2: integer): integer;
begin
Result := V1 + V2;
Showmessage(inttostr(result));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
P: Pointer;
begin
P := @XX;
TFunc(P)(1,2);
end;
lihuasoft 2008-09-27
  • 打赏
  • 举报
回复
为第一个问题作了一个方案:



{-----------以下是测试用的Project.DLL------------------}
library Project1;

uses
SysUtils,
Classes;

function Test(V1, V2, V3, V4, V5: integer): integer;stdcall;
begin
Result := V1 + V2*V3 - V4 div V5;
end;

exports
Test;
{$R *.res}

begin
end.

{---------------以下是调用----------------}

type
TArr = array of integer;

function RunDllFunc(DllName, FuncName: string; Para: TArr): integer;
var
H: THandle;
F : function:integer;stdcall;{按楼主要求,这样声明的}
Rst: integer;
begin
H := Windows.LoadLibrary(PChar(DllName));
if H<>0 then begin
@F := GetProcAddress(H, PChar(FuncName));
end;
asm
mov edi, Para
mov edx, [edi]-4
@AGAIN:
mov eax, [edi]+edx*4-4
push eax
dec edx
cmp edx, 0
jz @DONE
jmp @AGAIN
@DONE:
call F
mov Rst, eax
end;
Result := Rst;
FreeLibrary(H);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Para : TArr;
Rst : integer;
begin
SetLength(Para, 5);
Para[0] := 2;
Para[1] := 4;
Para[2] := 5;
Para[3] := 9;
Para[4] := 3;
Rst := RunDllFunc('project1.dll', 'Test', Para);
Showmessage(InttoStr(Rst));{2 + 4*5 - 9/3 = 19}
end;

{只要Para的元素个数与DLL函数的参数个数一致,就可以了。}
喝口水 2008-09-27
  • 打赏
  • 举报
回复
GetProcAddress函数返回的一个地址
我想如果楼主懂指针的话,上面的问题应该不难理解
hongqi162 2008-09-27
  • 打赏
  • 举报
回复
你随便找个dll改一下名替换一下你用的dll,然后使用第二中方法试一下
hongqi162 2008-09-27
  • 打赏
  • 举报
回复
判断一下你得这个函数在这个dll里面是否找到了,第二种情况容易没有进行这个判断容易出现异常

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧