我写了一个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.返回值无法回写.这是什么问题,各位帮我看看.
解决方案 »
- 两个Form之间的刷新Datagrid的问题
- 关于delphi通过adsl访问远程数据库的问题(悬赏100分)
- 如何用串口发送ASCII码??我希望用Spcomm控件来发送和接收。
- 请问如何将一个Binary的字符串转换为本10进制的?
- 谁会做实时抓取股票数据的程序?
- 已经连续四个通宵了。散30分吧~~~10点半结(睡觉)
- 那里能下在 TdxDBTreeList
- sql语句的order by的问题
- 高分:怎样修改数据库服务器时间,通过客户端??????
- 各位大侠帮帮忙:在dbgrid控件上,当把所有的记录都选上后,怎么才能点其中一条纪录时,使这条记录不选中,而其他记录仍然选中?
- 我的Blog文章:我的前沿科学(科学史上最新发现!将轰动整个学术界 )
- 继续散分,目前你在CSDN社区有可用分:9080
只能用PChar的
这句就是调用动态库中函数啊!