dll传递参数问题 ( 积分: 100 )

  • 主题发起人 主题发起人 erqie
  • 开始时间 开始时间
E

erqie

Unregistered / Unconfirmed
GUEST, unregistred user!
哪位大哥讲讲写dll给它传递不同类型参数的用法.包括传递数组,传递记录,传递动态数组,传递指针等.按照delphi自带的帮助讲dll的,那个
type
TTime=record
hour:Integer;
minute:Integer;
second:Integer;
end;
的记录,我随便写了一个过程:
procedure GetTime(var Time:TTime);stdcall;
begin
Time.hour:=1;
Time.minute:=2;
time.second:=100;
end;
在调用的时候
procedure TForm1.btn1Click(Sender: TObject);
type
TPro=procedure(var time:TTime);
var
han:THandle;
Pro:TPro;
ti:TTime;
begin
han:=LoadLibrary('project2.dll');
if han<>0 then
begin
@pro:=GetProcAddress(han,'GetTime');
Pro(ti);
ShowMessage('ti.second='+inttostr(ti.second));
FreeLibrary(han);
end;
end;
显示的总是一串数字.我需要怎么做才能使ti.second为100啊.
 
熟悉的朋友帮帮忙啊.这个是怎么回事啊?
 
Pro(ti);////应该传ti的地址过去 改为 Pro(@ti);
 
定义的时候是用的TPro=procedure(var time:TTime);
参数里是一个TTime的记录而不是指针啊.改成pro(@ti)编译器提示参数类型不一致.
 
看看这样行不行,用指针类作为参数
type
PTime=TTime^;
type
TTime=record
hour:Integer;
minute:Integer;
second:Integer;
end;
的记录,我随便写了一个过程:
procedure GetTime(Time:PTime);stdcall;
begin
Time.hour:=1;
Time.minute:=2;
time.second:=100;
end;
在调用的时候
procedure TForm1.btn1Click(Sender: TObject);
type
TPro=procedure(time:PTime);
var
han:THandle;
Pro:TPro;
ti:TTime;
begin
han:=LoadLibrary('project2.dll');
if han<>0 then
begin
@pro:=GetProcAddress(han,'GetTime');
Pro(@ti);
ShowMessage('ti.second='+inttostr(ti.second));
FreeLibrary(han);
end;
end;
 
//定义的时候是用的TPro=procedure(var time:TTime);
//参数里是一个TTime的记录而不是指针啊.改成pro(@ti)编译器提示参数类型不一致.

真有你的,定义时改为指针类型不就得了。TPro=procedure(time:PTime);
我觉得你的Dll不用修改

DLL与宿主程序之间传递参数,用标准指针多方便?为啥非要用Delphi的说法
 
enterwin的定义不对吧.应该是type PTime=^TTime;才是指针定义吧?我改成这样后还是不正确.
JohnYale说的我也试了一下,还是不行.另外我发现,在宿主程序里的ti指针地址与dll里的形参地址不一样.显示的结果还是在宿主程序里程序自动为参数ti分配的一个数值.挺长的.

我是初学这些东西,所以就随便找了个例子来跑一下,结果还不成功.用的是D7跑的.

另外如果是要在dll中返回一个字符串的话,用pchar的类型,而且在给它赋值的时候只能用strcopy函数,而不能用str:='aaa',这个是不是因为参数是指针的原因?那么对一个整数类型的返回值,如果不用a:=123;的话,那应该如何给它赋值?

初学,好多东西都不太明白.可以提供一个可以跑出正确结果的例子程序吗?谢谢了.
 
1.不要定义一些名字很特殊的结构体TTime
2.GetTime出现在 SysUtils单元中
3.procedure GetTimeSS(var TimeSS:TTimeSS) ;//stdcall;不需要stdcall就可以了,另外是如果需要stdcall;TPro=procedure(var time:TTime);中也是需要stdcall的,但stdcall的调用约定在传动态参数结构体应该会出现问题的
 
谢谢ztf86781163的提醒,经修改了记录的名字调整后终于跑成功了.没想到会是在这里出了问题.按理说自定义的类型如果与系统定义的类型重名的话应该会覆盖系统的(按变量生存环境来理解的,局部变量跟全局变量可以重名,但在局部过程里是局部变量起作用,可能有误).

因为在很多地方看到的结果说stdcall在函数有两个以为参数的时候都要加,否则参数的传递顺序可能不一致会导致错误,所以我才默认加了一个,实验的结果如ztf86781163所说,如果在dll里加了的话,在宿主程序里也要加.如果不加在有两个参数时会有错误.

修改后直接按记录为参数,或者按JohnYale说的用指针传递都可以.

虽然还有一些问题不是很明白,但目前还是有点理解了.
 
感谢各位的指导,接受答案了.
 
多人接受答案了。
 
后退
顶部