再问dll调用问题

Blakhawk 2006-07-17 12:17:53
我写了一个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.返回值无法回写.

这是什么问题,各位帮我看看.
...全文
271 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
很土 2006-07-26
  • 打赏
  • 举报
回复
压栈顺序不正确的话, 参数传递当然会出问题了.

若压栈个数不正确的话会出大问题, 可能会导致程序崩溃.
Blakhawk 2006-07-24
  • 打赏
  • 举报
回复
问题是参数传递问题没有解决啊.
很土 2006-07-24
  • 打赏
  • 举报
回复
CALL PFunc // 调用方法
这句就是调用动态库中函数啊!
Blakhawk 2006-07-22
  • 打赏
  • 举报
回复
我的string类型只是传送DLL完整地址和接口函数名称啊,这和实际的调用没关系的,
很土 2006-07-20
  • 打赏
  • 举报
回复
问题很大, 你写的汇编代码问题非常大

首先, 你是假设函数的调用协议是 register, 而 Windows 下一般的 API 基本上是 stdcall

其次, stdcall, cdecl 压栈顺序是从右到左, register 和 pascal 是从左到右

最后, stdcall, cdecl 对结构数据传递总是通过压栈, 按4字节方式压入

好好琢磨一下调用协议及参数传递和返回值处理
huang110 2006-07-19
  • 打赏
  • 举报
回复
Mark
Blakhawk 2006-07-18
  • 打赏
  • 举报
回复
还有其他问题没有.
ly_liuyang 2006-07-18
  • 打赏
  • 举报
回复
DLL的接口用了String本来就是错误
只能用PChar的
Blakhawk 2006-07-17
  • 打赏
  • 举报
回复
怎么没有人帮忙啊.

16,748

社区成员

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

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