现在要写个函数,有多个输入参数和输出参数,
现不知道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?各位能不能贴个这种有多个输入参数和输出参数的函数给我参考一下呀.
非常感谢.

解决方案 »

  1.   

    函数的返回值只有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中可以考虑内存映射修改共享数据。
      

  2.   

    现在还有两个问题:
    1。在声明时如何区分哪些是输入参数,哪些是输出参数?
    如我的之前写的函数:
    function Read_Card(port,password:pchar;out factory,cardno,factor,writeno
    :pchar):pchar;stdcall;
    这里面有个out,是不是out后面的都是输出参数呀?
    2。在调用这个函数时,如何取出这个函数的某个输出参数的值?
      

  3.   

    一个函数的返回值是只有一个,当需要返回多个值的时候,我们就需要用传址来实现了,在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种方法就可以了,我这里不多说
      

  4.   

    谢谢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,也没办法取到这个函数的传出参数的值。请指点,谢谢。
      

  5.   

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

  6.   

    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;
      

  7.   

    你为什么那么死的要认为得加out才是出参呢,这又不是pl/sql的存储.不是和你说了吗,用传址对函数里面的改变就反应到实际参数里了。上面的例子初始化一个1024的PChar,函数里再用StrCopy(P,PChar(num));将num的内容拷贝到p里,把调用的ShowMessage('succ');这句改成
    ShowMessage(String(P));你看看结果.
      

  8.   

    以你现在的情况可能对付c++的调用还稍微好点,java的调用估计也得折腾一段时间了
      

  9.   

    多谢fenger8293指点,我正在试。我现在必须要做成active x类型的dll,因为它里面有dllregisterserver函数,才能进行注册,
    客户的b/s系统,让他的jsp以及vbscript来调用这个dll.客户说之前别人用c++,vb做的dll,他们调用都是可以的。
      

  10.   

    fenger8293:你好,
    ShowMessage(String(P));你看看结果.我这边显示出来的总是乱码呀。
    1T,HI这样子的。
      

  11.   

    主要问题是好像程序没有执行这行代码: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,请问是什么原因?非常感谢。
      

  12.   

    我是因为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.
      

  13.   

    我试了,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指点呀,
    多谢。
      

  14.   

    fenger你好,我现在上不了qq,可以上msn,我的msn:[email protected]
    我们在msn上聊好吗?我急呀。
    谢谢。
      

  15.   

    fenger,你好,
    主要问题是我按你的代码,运行的结果是:
    ShowMessage(string(P)); 显示出来的是一个“?",
    你那里显示出来的是this is a demo!吗?加我msn呀。