dll中的函数的返回多个参数的问题.

yikeshu_888 2007-06-12 06:03:27
现在要写个函数,有多个输入参数和输出参数,
现不知道delphi中如何编写这种函数,主要是不知道语法,格式.

我现在是这样写的:
function Read_Card(port,password:pchar;out factory,cardno,factor,writeno
:pchar):pchar;stdcall;
begin
factory:='mytest1';
cardno:='mytest2';
writeno:='mytest3';
result:='ok';
end;

不知道上述写法对不对,另外应当如何调用这个函数,以取得这个函数的某个返回参数的值,如想取得cardno的值为:mytest2?

各位能不能贴个这种有多个输入参数和输出参数的函数给我参考一下呀.
非常感谢.

...全文
810 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
手指风 2007-06-15
  • 打赏
  • 举报
回复
我是因为dll里有窗体,所以用了try和finally.我给你重新写了一个demo,
以下是应用的主要代码
function ReturnCall(P:PChar):Boolean;stdcall;external 'trade.dll';
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
P:PChar;
begin
try
P:=StrAlloc(1024);
if ReturnCall(P) then
ShowMessage(string(P));
finally
StrDispose(P);
end;
end;

dll的如下:
uses
SysUtils,
Classes;

function ReturnCall(P:PChar):Boolean;stdcall;
begin
StrCopy(P,'this is a demo!');
Result:=True;
end;
exports
ReturnCall;
{$R *.res}

begin
end.
yikeshu_888 2007-06-15
  • 打赏
  • 举报
回复
fenger,你好,
主要问题是我按你的代码,运行的结果是:
ShowMessage(string(P)); 显示出来的是一个“?",
你那里显示出来的是this is a demo!吗?

加我msn呀。
yikeshu_888 2007-06-15
  • 打赏
  • 举报
回复
fenger你好,我现在上不了qq,可以上msn,我的msn:debao-li@hotmail.com
我们在msn上聊好吗?我急呀。
谢谢。
手指风 2007-06-15
  • 打赏
  • 举报
回复
晕,真累啊.按你改的运行结果应该是报地址错的.你对PChar和指针的概念理解还是不行.
P:=StrAlloc(1024);这句分配1k的字符内存给指针p,p:=pchar('test');你加了这句后,p就指向了常量'test'的内存了.这时候原来的1k已经被泄漏了.后面在dll里再往p的内存里做strcopy就是错误的内存操作了,因为常量内存是不能修改的.
你把p:=pchar('test');这句改成P:=StrCopy(P,'test');这样再运行,结果就正常了.
我QQ:9870525,还有问题直接给我qq消息好了.

yikeshu_888 2007-06-15
  • 打赏
  • 举报
回复
我试了,ShowMessage(string(P)); 显示出来的是一个“?",你那里显示出来的是正常的吗?
我猜想dll定义的p和调用时定义的p是不是同一个p呀?

现我又加了一句p:=pchar('test');
try
P:=StrAlloc(1024);
p:=pchar('test');
if ReadICCard(P) then
ShowMessage(string(P));
finally
StrDispose(P);
end;
则显示出来的仍是test,而不是我们期望的:this is a demo!

请fenger指点呀,
多谢。
yikeshu_888 2007-06-14
  • 打赏
  • 举报
回复
谢谢fenger8293
传出参数的前面要不要加out以示为传出参数?而且在函数声明的时候还要加var?
"一般这种返回参数比较多的情况,要返回数据的参数都在函数里面定义"
还有我在函数体内给传出参数赋值的话,是不是也在先在函数体内先定义?
如下:
function Read_Card(const port,password:pchar;out factory,cardno,factor,writeno,res
:pchar):Boolean;stdcall;
var factory,cardno,factor,writeno,res:pchar;
begin
factory:='11111';
cardno:='22222';
factor:='33333';
writeno:='4444';
res:='5555';

result:=true;
end;

我要做的这个函数就是一个读IC卡的函数,要求是传入两个参数值,然后传出30个返回值给别的系统,
别的调用这个dll的系统是用c++,还有java等写的.

现在的问题还有我就是用delphi做一个调用程序demo.exe,也没办法取到这个函数的传出参数的值。

请指点,谢谢。
手指风 2007-06-14
  • 打赏
  • 举报
回复
一个函数的返回值是只有一个,当需要返回多个值的时候,我们就需要用传址来实现了,在delphi里所有的对象都是传址的,所以如果你传入一个TEdit的对象的话,实际对edit的操作是会反应到实参里的.你上面写的函数如果是用PChar来做参数的话,已经就是一个传址了.因为PChar本身就是一个指针,还有要注意要使dll被其他语言调用的话不要用string,否则会比较麻烦的.不知道你的函数需要实现什么功能,给你一个例子,比如按我对你的上面的声明进行理解,以port和password作为入参,其他全为出参,可以写成这样
function Read_Card(const port,password:pchar;factory,cardno,factor,writeno,res
:pchar):Boolean;stdcall;
一般这种返回参数比较多的情况,要返回数据的参数都在函数里面定义,返回值用来表示函数是否成功调用.你也可以返回integer并约定数字的意义,另外可以在参数里加上如果函数执行错误的话的错误或警告信息.当然这些都是根据你的实际情况去定就可以了
至于函数的调用,去搜索delphi对dll的静态和动态调用2种方法就可以了,我这里不多说
yikeshu_888 2007-06-14
  • 打赏
  • 举报
回复
顶一下。
yikeshu_888 2007-06-14
  • 打赏
  • 举报
回复
主要问题是好像程序没有执行这行代码:StrCopy(P,PChar(num));

我把你的程式改成如下:
dll中的函数如下:
function ReadICCard(var P:PChar):Boolean;stdcall;
var num:string;
begin
num:='aaa';
StrCopy(P,pchar(num));
Result:=True;
end;

demo.exe调用程式的button调用如下:
procedure Tuseprog.Button1Click(Sender: TObject);
var
P:PChar;
begin
try
P:=StrAlloc(1024);
p:=pchar('test');
if ReadICCard(P) then
showmessage(string(p));
finally
StrDispose(P);
end;

end;

这时候showmessage(string(p));显示出的值是test,而不是我们期望的aaa
请问是为什么?

另:在dll函数中我想写成:
try
StrCopy(P,pchar(num));
Result:=True;
finally
Free;
end;

可编译时总是提示说不认识free,请问是什么原因?

非常感谢。
yikeshu_888 2007-06-14
  • 打赏
  • 举报
回复
fenger8293:你好,
ShowMessage(String(P));你看看结果.

我这边显示出来的总是乱码呀。
1T,HI这样子的。
yikeshu_888 2007-06-14
  • 打赏
  • 举报
回复
多谢fenger8293指点,我正在试。

我现在必须要做成active x类型的dll,因为它里面有dllregisterserver函数,才能进行注册,
客户的b/s系统,让他的jsp以及vbscript来调用这个dll.

客户说之前别人用c++,vb做的dll,他们调用都是可以的。
手指风 2007-06-14
  • 打赏
  • 举报
回复
以你现在的情况可能对付c++的调用还稍微好点,java的调用估计也得折腾一段时间了
手指风 2007-06-14
  • 打赏
  • 举报
回复
你为什么那么死的要认为得加out才是出参呢,这又不是pl/sql的存储.不是和你说了吗,用传址对函数里面的改变就反应到实际参数里了。上面的例子初始化一个1024的PChar,函数里再用StrCopy(P,PChar(num));将num的内容拷贝到p里,把调用的ShowMessage('succ');这句改成
ShowMessage(String(P));你看看结果.



手指风 2007-06-14
  • 打赏
  • 举报
回复
var
Form1: TForm1;
num:string;
function ReadICCard(P:PChar):Boolean; stdcall;
implementation

{$R *.dfm}

function ReadICCard(P:PChar):Boolean;
begin
num:='aaa';
with TForm1.Create(nil) do
try
ShowModal;
StrCopy(P,PChar(num));
Result:=True;
finally
Free;
end;
end;
下面是调用
function ReadICCard(P:PChar):Boolean;stdcall;external 'aa.dll';
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
P:PChar;
begin
try
P:=StrAlloc(1024);
if ReadICCard(P) then
ShowMessage('succ');
finally
StrDispose(P);
end;
end;
yumo1218 2007-06-14
  • 打赏
  • 举报
回复
可以定义输入输出参数,那样就可以有多个参数回传了,只要把那些参数赋值就可以
yikeshu_888 2007-06-14
  • 打赏
  • 举报
回复
再顶。
yikeshu_888 2007-06-14
  • 打赏
  • 举报
回复
现在的问题还有我就是用delphi做一个调用程序demo.exe,也没办法取到这个函数的传出参数的值。

如何取得这个函数的传出参数的值?

谢。
yikeshu_888 2007-06-13
  • 打赏
  • 举报
回复
现在还有两个问题:
1。在声明时如何区分哪些是输入参数,哪些是输出参数?
如我的之前写的函数:
function Read_Card(port,password:pchar;out factory,cardno,factor,writeno
:pchar):pchar;stdcall;
这里面有个out,是不是out后面的都是输出参数呀?
2。在调用这个函数时,如何取出这个函数的某个输出参数的值?
yikeshu_888 2007-06-12
  • 打赏
  • 举报
回复
函数的返回值只有1个?不能有多个返回值吗?
现在我的客户要求写这样的函数呀,有多个传入的参数,以及多个返回的参数,
那我该怎么办呀.

有没有这方面的简单的例子函数,贴出来给我参考一下,
非常感谢.
slzzg 2007-06-12
  • 打赏
  • 举报
回复
函数的返回值只有1个,而且是返回在EAX寄存器中;

如果要在函数体中有多个返回值,可以考虑实参掉用;参数前面+var,默认为形参掉用
function Read_Card(var port,password:pchar;var factory,cardno,factor,writeno
:pchar):pchar;stdcall;
begin
factory:='mytest1';
cardno:='mytest2';
writeno:='mytest3';
result:='ok';
end;

另外在Dll中可以考虑内存映射修改共享数据。

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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