delphi2007 教程

delphi2007 教程

首页 新随笔 联系 聚合 管理
  1013 Posts :: 0 Stories :: 28 Comments :: 0 Trackbacks
数组指针问题,看起来简单做起来复杂,大家帮忙啊! Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiDB/html/delphi_20061219113016224.html
我首先做了一个DLL   名字是“mydll”  
   
  library   MYDLL;  
   
  uses  
      sharemem,  
      SysUtils,  
      ExtCtrls,  
      StdCtrls;  
   
   
      type   Tps   =   Record  
                    sno:   integer;   //序列号  
                    fjcode:string[200];//代号  
      End;  
      Tp=array   of   Tps;  
      PTp   =   ^TP;  
   
  {$R   *.RES}  
   
  function   Select(var   PResult:PTp):integer;   export;   stdcall;  
  begin  
      try  
          new(PResult);  
          setlength(PResult^,2);  
          PResult^[0].sno:=1;    
          PResult^[0].fjcode:='大大';  
          PResult^[1].sno:=2;    
          PResult^[1].fjcode:='小小';  
          result:=1;  
      finally  
          dispose(PResult);  
      end;  
  end;  
   
  exports  
      Select;  
   
  begin  
   
  end.  
   
   
  然后我用DELPIH用以下程序调用  
  var  
      Form1:   TForm1;  
   
      type  
          Tps   =   Record  
                    sno:   integer;   //序列号  
                    fjcode:pchar;//系列代号,如DBF  
      End;  
      Tp=array   of   Tps;  
      PTp   =   ^TP;  
  implementation  
   
  {$R   *.DFM}  
  function   Select(var   PResult:PTp):integer;   export;   stdcall;  
                  external   'mydll.dll';  
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
  var   presult:PTp;  
          i:integer;  
  begin  
      i:=Select(PResult);  
      showmessage(PResult^[0].fjcode);//为什么会在这行错误呢???  
      showmessage(PResult^[1].fjcode);  
  end;  
   
  现在的问题是我看了我的DLL应该是没有问题的!  
        为什么showmessage(PResult^[0].fjcode);显示不出‘大大’两个字,反而报错‘内存访问错误’!  
        我该如何查看调用了DLL后函数中输出值PResult的输出结果‘大大’这两个字呢?

帖子贴出来已经一个小时了,在线等了一个多小时了,好着急,高手帮忙啊!

http://community.csdn.net/Expert/topic/5238/5238067.xml?temp=.7243158  
 

maozefa(阿发伯)兄弟,因为我传进去的数组开多大是事先不知道的,所以必须在DLL中去动态setlength,我该怎么写呢?  
  另外象您将的先开好数组然后进去DLL赋值,那我又该做什么修改才能得到我的‘大大’这个输出结果呢?希望您不吝赤教啊,我水平不太好,又被逼到这个地步了,希望能得到您的指导!!!

首先,修改结构:  
  Tps   =   packed   Record  
          sno:   integer;   //序列号  
          fjcode:array[0..199]   of   char;  
  end;  
  其次,Dll中增加一函数,返回数组大小。应用程序中先调用该函数,然后分配内存。  
  用指针作为参数调用Dll的Select  
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
  var    
          presult:Tps;  
          i,   Count:   integer;  
  begin  
      Count   :=   GetSelectCount;   //假设Dll增加的函数,返回数组个数。  
      SetLength(presult,   Count);  
      i:=Select(@PResult);  
      showmessage(PResult^[0].fjcode);  
      showmessage(PResult^[1].fjcode);  
  end;  
   
   
  没有测试,共参考。  
 

我按您的方法做了,就是先分配地址后调用DLL  
  可是按您的代码:  
   
      SetLength(presult,   Count);//有错误,应该是SetLength(presult^,   Count);//  
      i:=Select(@PResult);//这句执行的时候说实参和形参类型不一样的。  
   
  现在还没有完成调试,就是说还没有得到‘大大’两个字出来,兄弟帮忙啊。。。

 
  type  
  Tps   =   packed   Record  
          sno:   integer;   //序列号  
          fjcode:array[0..199]   of   char;  
  end;  
  PTp   =   ^Tps;  
  TpArray   =   array   of   Tps;  
   
  function   Select(PResult:PTp):integer;   export;   stdcall;  
  begin  
          TpArray(PResult)[0].sno:=1;  
          TpArray(PResult)[0].fjcode:='大大';  
          TpArray(PResult)[1].sno:=2;  
          TpArray(PResult)[1].fjcode:='小小';  
          result:=1;  
  end;  
   
  function   GetSelectCount:   Integer;   export;   stdcall;  
  begin  
      Result   :=   2;  
  end;  
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
  var  
          presult:Ptp;  
          i,   Count:   integer;  
  begin  
      Count   :=   GetSelectCount;   //假设Dll增加的函数,返回数组个数。  
      GetMem(PResult,   sizeof(Tps)   *   Count);  
      try  
          i:=Select(PResult);  
          showmessage(TpArray(PResult)[0].fjcode);  
          showmessage(TpArray(PResult)[1].fjcode);  
      finally  
          FreeMem(PResult,   sizeof(Tps)   *   Count);  
      end;  
  end;  
 

我已经全面测试,没问题的:  
  library   Project2;  
   
  uses  
      SysUtils,  
      Classes;  
  type  
  Tps   =   packed   Record  
          sno:   integer;   //序列号  
          fjcode:array[0..199]   of   char;  
  end;  
  PTp   =   ^Tps;  
  TpArray   =   array   of   Tps;  
   
  function   Select(PResult:PTp):integer;   export;   stdcall;  
  begin  
          TpArray(PResult)[0].sno:=1;  
          TpArray(PResult)[0].fjcode:='大大';  
          TpArray(PResult)[1].sno:=2;  
          TpArray(PResult)[1].fjcode:='小小';  
          result:=1;  
  end;  
   
  function   GetSelectCount:   Integer;   export;   stdcall;  
  begin  
      Result   :=   2;  
  end;  
   
  {$R   *.res}  
  exports  
  Select,  
  GetSelectCount;  
   
  begin  
  end.  
   
   
   
  type  
  Tps   =   packed   Record  
          sno:   integer;   //序列号  
          fjcode:array[0..199]   of   char;  
  end;  
  PTp   =   ^Tps;  
  TpArray   =   array   of   Tps;  
   
  function   GetSelectCount:   Integer;   stdcall;   external   'Project2.dll';  
  function   Select(PResult:PTp):integer;   stdcall;   external   'Project2.dll';  
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
  var  
          presult:Ptp;  
          i,   Count:   integer;  
  begin  
      Count   :=   GetSelectCount;   //假设Dll增加的函数,返回数组个数。  
      GetMem(PResult,   sizeof(Tps)   *   Count);  
      try  
          i:=Select(PResult);  
          showmessage(TpArray(PResult)[0].fjcode);  
          showmessage(TpArray(PResult)[1].fjcode);  
      finally  
          FreeMem(PResult,   sizeof(Tps)   *   Count);  
      end;  
   
  end;  
 

maozefa(阿发伯)   谢谢,按您的方法结果出来了!不过我想追问一个问题:  
  type  
  Tps   =   packed   Record  
          sno:   integer;   //序列号  
          fjcode:array[0..199]   of   char;  
  end;  
  PTp   =   ^Tps;  
  TpArray   =   array   of   Tps;  
   
  按您的这种方法定义和使用dll(就是ARRAY   OF   ...)其他语言调用我DELPHI写的DLL的时候会不会问题呢?  
  谢谢您的回复,您就是我的恩人啊。。。

没问题的,其他语言,比如C/C++的指针可以直接用下标的。  
  另外,把Dll中的function   Select(PResult:PTp):integer;   export;   stdcall;  
  改为function   Select(var   PResult:PTp):integer;   export;   stdcall;  
   
  就可直接用SetLength分配数组长度了  
  procedure   TForm1.Button1Click(Sender:   TObject);  
  var  
          presult:   array   of   Tps;  
          i,   Count:   integer;  
  begin  
      Count   :=   GetSelectCount;   //假设Dll增加的函数,返回数组个数。  
      SetLength(presult,   Count);  
      i:=Select(@PResult);  
      showmessage(PResult[0].fjcode);  
      showmessage(PResult[1].fjcode);  
  end;  
 

但是,程序中的函数说明不要改。  
  还是function   Select(PResult:PTp):integer;   stdcall;   external   'Project2.dll';

使用下面的定义,就是方便其他语言如c/c++定义结构的  
  Tps   =   packed   Record

实在太感谢了,有好多东西我还要边看边理解的!感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢

posted on 2009-02-19 16:55 delphi2007 阅读(83) 评论(0)  编辑 收藏 引用
只有注册用户登录后才能发表评论。