本人水平有限,02年时候做过1年数据库,如今时隔7年重操旧业义务替单位做个数据库程序,但发现时代进步我没进步,唉,厚颜向各位高手求教,谢谢了!本来都放在数据主程序中是很简单的,但我觉得那样做主程序会显得冗余庞大,所以想将报表打印这块独立出来,然后将数据库查询结果或者query对象本身传递给DLL,在DLL中打印。我试过将query对象本身传递给DLL,但是出地址错误。在网上搜索了下有网友建议:      “不要把对象直接传给DLL,而要把对象及其操作包装成普通函数和指针再传递给DLL,就像windows   API那样,否则你的程序会死的很残” 以下是他的方法。function   OpenSQL(SQL:   pchar):   pointer;stdcall;  
  var  
      qry:   TQuery;  
  begin  
      qry   :=   TQuery.Create(...);  
      qry.SQL.Text   :=   SQL;  
      qry.Open;  
      Result   :=   qry;  
  end;  
   
  type  
  RQueryOprs   =   record  
      function   OpenSQL(SQL:   pchar):   pointer;stdcall;  
      function   ExecSQL(SQL:   pchar):   integer;stdcall;  
      function   Eof(Query:   pointer):   boolean;stdcall;  
      ....  
  end;  

  PQueryOprs   =^RQueryOprs;  
   
  const  
      query_oprs:   RQueryOprs   =   (  
          OpenSQL:   thispage.OpenSQL;  
          ExecSQL:   thispage.ExecSQL;  
          Eof:   thispage.Eof;  
          ....  
      );  
   
  将query_oprs的地址传入DLL即可,DLL可以通过函数表操作任何类型的SQL数据库  
  为方便使用可以在DLL中将函数表包装成类上面这个红字部份,函数放在记录类型编译就通不过啊。我以前也试过直接传递QUERY对象指针,但是失败了,他这样行不行?

解决方案 »

  1.   

    dll中声明一个var qry:Tquery;
    一个function getqry:query;
        begin
          qry:=Tquery.create(self);
          result:=qry;
        end;调用后得到QUERY中的 qry
    var
      TemQry:Tquery;
      TemQry:=getqry;
      temqry.assign(查询出结果的数据集);然后 dll中的qry应该就有数据了 
                 
                 
      

  2.   

        上面那个temqry.assign赋值出错,信息居然是:cannot assign a Tquery to  a Tbutton,奇怪的错误。
       另外我自己做了个测试,出pointer错误,请帮我分析下,下面分别是主程序和DLL代码:主程序一个窗体,放了个database1,query1,连接好数据库。unit main;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, DB, Grids, DBGrids, DBTables;type
      Tmainfrm = class(TForm)
        catvdb: TDatabase;
        Query1: TQuery;
        Button1: TButton;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      mainfrm: Tmainfrm;
      function   passquery(aquery:pointer):   pointer;stdcall
          external   'printreport.DLL' name   'passquery'; 
    implementationuses Unit2;{$R *.dfm}procedure Tmainfrm.Button1Click(Sender: TObject);
    begin
      passquery(@query1);
    end;end.
    DLL 代码,包含一个窗体,上有一个datasource,dbgrid组件显示数据:library printreport;uses
      SysUtils,
      Classes,
      Forms,
      dbtables,
      unit1 in 'unit1.pas' {Form1};{$R *.res}function passquery(aquery:pointer) :pointer;
    var
      TemQry:Tquery;
    begin
      form1:=Tform1.create(nil);
      form1.Show;  //创建一个窗体,显示主程序query1传递过来的数据。
      TemQry:=tquery(aquery^);
      //TemQry.Assign(tquery(aquery^));
      form1.DataSource1.DataSet:=TemQry;
    end;  exports  
          passquery;begin
    end.