一个动态调用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是什么意思?
谢谢先!!
开始是要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是什么意思?
谢谢先!!
解决方案 »
- 怎么隐藏进程?网上找了那个说能隐藏的很多行的代码结果发现还是没隐藏
- 关闭含有OCX的IE窗口报错的问题,大富翁中没有人回答,转战此地,请大家指教!
- 关于tcpsokcet连接的问题
- 调试时如何查看变量值的改变
- 为什么打印窗体上面的panel 在A4的纸上面 只有 A4 的 1/4 大小呢,该怎么样做 代码如下:
- 怎么可以让Tpagecontrol的格式变成横着的,详情请进(无未结帖记录)
- 如何 加密自已的配置文件
- 在SQLServer7.0中两台机器的数据库HS的表FuncTree的相互更新
- google今天入口
- 请教一个关于listView的问题
- 初学delphi 遇到pascal语言的时候很难理解。
- delphi中怎么对带有括号的列名进行查询?
我想如果楼主懂指针的话,上面的问题应该不难理解
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函数的参数个数一致,就可以了。}
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;
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;
我想如果楼主懂指针的话,上面的问题应该不难理解~~~
@myfun表示的是myfun变量的地址
GetProcAddress按字面意思就可以知道,是指返回过程的地址。(如果找不到,返回nil)
if Assigned(@myfun) then 也就是if @myfun<>nil then 两者一个意思。
但是,前者显得"高级"一点,让lz这样初次碰到的时候感觉茫然。
个人认为,使用第一种比较好,万一,你把dll中改掉了,那么就会出现报地址错误,不好看了。