我写了一个dll :
文件名:myRun.dll,包涵一个form
接口函数:function Execute(AHandle:HWnd;para1:integer):string; export; stdcall;实现如下:
function Execute(AHandle:HWnd ;para1:integer):string;
var
msg : string;
begin
Result :='Fault';
try
Application.Handle:=THandle(AHandle);
Application.CreateForm(TdemofrmForm,demofrmForm);
with demofrmForm do
begin
ListBox1.Items.clear;
ListBox1.Items.Add('Input params:'+#13#10);
ListBox1.Items.Add('[Handle]:'+vartostr(AHandle));
ListBox1.Items.Add('[param1]:'+inttostr(para1));
ShowModal;
Result :='OK';
end;
except
on E: Exception do
messagebox(0,pchar(e.Message),'Execute',mb_iconwarning)
end;
end;
主调用函数定义如下:
function Rundll32(xdll: string; AName: string;
Params: array of const): DWord;
const
RecSize = SizeOf(TVarRec);
var
PFunc: Pointer;
ParCount: DWord;
AHandle :THandle;
begin
AHandle:=LoadLibrary(pchar(xdll));
if AHandle=0
then Exit;
PFunc := GetProcAddress(AHandle,pchar(AName));
if not Assigned(PFunc) then
raise Exception.CreateFmt('找不到 %s 的 Method: %s', [xdll,
AName]); ParCount := High(Params) + 1; // 获取参数个数 asm
PUSH ESI // 保存 ESI,我们待会儿要用到它 MOV ESI, Params // ESI 指向参数表首址
CMP ParCount, 1 // 判断参数个数
JB @NoParam
JE @OneParam
CMP ParCount, 2
JE @TwoParams
CMP ParCount, 3
JE @Threeparams @ManyParams: // 超过三个参数
CLD // 清空方向标志
MOV ECX, ParCount
SUB ECX, 3 // 循环 ParCount - 3次
MOV EDX, RecSize // EDX 依次指向每个参数的首址,每次递增 8 Bytes
ADD EDX, RecSize // 跳过前两个参数
@ParamLoop:
MOV EAX, [ESI][EDX] // 用基址变址寻址方式取得一个参数
PUSH EAX // 参数进栈
ADD EDX, RecSize // EDX 指向下一个参数首址
LOOP @ParamLoop @Threeparams: // 三个参数
MOV ECX, [ESI] + RecSize +RecSize @TwoParams: // 两个参数
MOV EDX, [ESI] + RecSize @OneParam: // 一个参数
MOV EAX, [ESI]
@NoParam:
CALL PFunc // 调用方法
MOV Result, EAX // 返回值放入 Result
POP ESI // 记得还原
end;
end;实际调用如下:
procedure TForm1.Button5Click(Sender: TObject);
begin
RunDll32('c:\myRun.dll','Execute',[Handle,123123]);
end;问题:
1.为什么dll调用总是报告无效句柄.
2.传递的参数总是不正确.
3.返回值无法回写.这是什么问题,各位帮我看看.
文件名:myRun.dll,包涵一个form
接口函数:function Execute(AHandle:HWnd;para1:integer):string; export; stdcall;实现如下:
function Execute(AHandle:HWnd ;para1:integer):string;
var
msg : string;
begin
Result :='Fault';
try
Application.Handle:=THandle(AHandle);
Application.CreateForm(TdemofrmForm,demofrmForm);
with demofrmForm do
begin
ListBox1.Items.clear;
ListBox1.Items.Add('Input params:'+#13#10);
ListBox1.Items.Add('[Handle]:'+vartostr(AHandle));
ListBox1.Items.Add('[param1]:'+inttostr(para1));
ShowModal;
Result :='OK';
end;
except
on E: Exception do
messagebox(0,pchar(e.Message),'Execute',mb_iconwarning)
end;
end;
主调用函数定义如下:
function Rundll32(xdll: string; AName: string;
Params: array of const): DWord;
const
RecSize = SizeOf(TVarRec);
var
PFunc: Pointer;
ParCount: DWord;
AHandle :THandle;
begin
AHandle:=LoadLibrary(pchar(xdll));
if AHandle=0
then Exit;
PFunc := GetProcAddress(AHandle,pchar(AName));
if not Assigned(PFunc) then
raise Exception.CreateFmt('找不到 %s 的 Method: %s', [xdll,
AName]); ParCount := High(Params) + 1; // 获取参数个数 asm
PUSH ESI // 保存 ESI,我们待会儿要用到它 MOV ESI, Params // ESI 指向参数表首址
CMP ParCount, 1 // 判断参数个数
JB @NoParam
JE @OneParam
CMP ParCount, 2
JE @TwoParams
CMP ParCount, 3
JE @Threeparams @ManyParams: // 超过三个参数
CLD // 清空方向标志
MOV ECX, ParCount
SUB ECX, 3 // 循环 ParCount - 3次
MOV EDX, RecSize // EDX 依次指向每个参数的首址,每次递增 8 Bytes
ADD EDX, RecSize // 跳过前两个参数
@ParamLoop:
MOV EAX, [ESI][EDX] // 用基址变址寻址方式取得一个参数
PUSH EAX // 参数进栈
ADD EDX, RecSize // EDX 指向下一个参数首址
LOOP @ParamLoop @Threeparams: // 三个参数
MOV ECX, [ESI] + RecSize +RecSize @TwoParams: // 两个参数
MOV EDX, [ESI] + RecSize @OneParam: // 一个参数
MOV EAX, [ESI]
@NoParam:
CALL PFunc // 调用方法
MOV Result, EAX // 返回值放入 Result
POP ESI // 记得还原
end;
end;实际调用如下:
procedure TForm1.Button5Click(Sender: TObject);
begin
RunDll32('c:\myRun.dll','Execute',[Handle,123123]);
end;问题:
1.为什么dll调用总是报告无效句柄.
2.传递的参数总是不正确.
3.返回值无法回写.这是什么问题,各位帮我看看.
解决方案 »
- 简单的问题(100分送快速接贴)
- 询问关于票据打印方面的思路
- 做软件N年了,却不知道模仿一个软件的界面是不是违法!自卑中
- Bitter_fish(苦鱼) 领分!
- 高分求教:如何在网络打印机打印纸时右下角打印工作站名称和统计各工作站打的纸数
- 我用query.sql.add(sysdate-数据库中的一个时间);但显示出来的不是时间的形式。我怎样把它换成分的形式啊?
- 如何取得系统的颜色位数,我用SystemPalette16可以取得16位以上的
- 对不起各位,今天csdn刚刚发布。请大家重新来测试一下我的处女作好么,欢迎参观
- 送给大家10本书
- ExtractFileDir()这个函数后面不能跟变量?
- 我的Blog文章:我的前沿科学(科学史上最新发现!将轰动整个学术界 )
- 继续散分,目前你在CSDN社区有可用分:9080
只能用PChar的
这句就是调用动态库中函数啊!