我在dll中的窗口用静态的DataSource连接动态的ADOQUERY(自己写的)出错
有朋友帮我看下好吗function Tpage.QueryCreate: pointer;
var
  ADOQ_page: TADOQuery;
begin
  try
  ADOQ_page := TADOQuery.Create(page);
  Result := pointer(ADOQ_page);
  except
  freeandnil(ADOQ_page);
  Result := nil;
  end;
end;function Tpage.QuerySql(PForm: pointer; SqlText: String): integer;
begin
  try
    if PForm <> nil then
    begin
    DataSource1.DataSet := TADOQuery(PForm);//问题?
    TADOQuery(PForm).Close;
    TADOQuery(PForm).ConnectionString := 
   'Provider=SQLOLEDB.1;Password=1980;Persist Security Info=True;User ID=sa;Initial Catalog=pubs;Data Source=WB-3B22F7D48C52';
    TADOQuery(PForm).SQL.Clear;
    TADOQuery(PForm).SQL.Text := SqlAdd;
    TADOQuery(PForm).Open;
    showmessage(inttostr(TADOQuery(PForm).RecordCount));
    end;
  except
    showmessage('出错');
  end;
end;

解决方案 »

  1.   

    function Tpage.QuerySql(PForm: pointer; SqlText: String): integer;
    var
      Qry:TAdoQuery;
    begin
    try
    if PForm <> nil then
    begin
    Qry := TADOQuery(PForm);
    DataSource1.DataSet := Qry;
    Qry.Close;
    Qry.ConnectionString :=
    'Provider=SQLOLEDB.1;Password=1980;Persist Security Info=True;User ID=sa;Initial Catalog=pubs;Data Source=WB-3B22F7D48C52';
    Qry.SQL.Clear;
    Qry.SQL.Text := SqlAdd;
    Qry.Open;
    showmessage(inttostr(Qry.RecordCount));
    end;
    except
    showmessage('出错');
    end;
    end;
      

  2.   

    把参数PForm: pointer;改成 PForm: TAdoQuery;就完了 干嘛用pointer 啊
      

  3.   

    您的问题出在Interface的生命周期管理上请注意TAdoQuery的来历TAdoQuery ---》 TCustomADODataSet = class(TDataSet, IUnknown, RecordsetEventsVt)function Tpage.QueryCreate: pointer;由于返回为pointer所以没有增加ADOQ_page的引用记数。由于Interface是自动销毁(当引用记数为0时)自然当你引用function Tpage.QueryCreate时内存的实例已经销毁了
      

  4.   

    sanmaotuo(老冯):
    还有一事请教
      我通过dll调用窗口对象与到问题
    在该窗口对象
    procedure Tpage.BtnViewClick(Sender: TObject);
    begin
      adoquery1.close;
      adoquery1.sql.clear;
      adoquery1.ConnectionString := 'Provider=SQLOLEDB.1;Password=1980;Persist Security Info=True;User ID=sa;Initial Catalog=pubs;Data Source=WB-3B22F7D48C52';
      adoquery1.sql.clear;
      adoquery1.sql.add('select * from jobs');
      adoquery1.sql.open;
    end;
    是可以的
    但是我把该内容做一个函数就不行了
    public
        function QuerySql(SqlAdd: String): integer;
        { Public declarations }
      end;
    function Tpage.QuerySql(SqlAdd: String): integer;
    begin
      adoquery1.close;
      adoquery1.sql.clear;
      adoquery1.ConnectionString := 'Provider=SQLOLEDB.1;Password=1980;Persist Security Info=True;User ID=sa;Initial Catalog=pubs;Data Source=WB-3B22F7D48C52';
      adoquery1.sql.clear;
      adoquery1.sql.add(SqlAdd);
      adoquery1.sql.open;
    end;procedure Tpage.BtnViewClick(Sender: TObject);
    var
      Sqlstr: String;
    begin
      Sqlstr := 'select * from jobs';
      page.QuerySql(sqlstr);
    end;
    却不行啊
      

  5.   

    看看我的例子,希望能给你启示:
    type
      TArr=array[0..2] of ShortString;
      PTArr=^TArr;function getspecial(a:PTArr):ShortString;StdCall;
    var
      ADOQ:TADOQuery;
      FileName:String;
    begin
      CoInitialize(nil);
      FileName:=ExtractFilePath(ParamStr(0))+'bin\MDB\Assistant.mdb';
      ADOQ:=TADOQuery.Create(nil);
      try
      with ADOQ do
      begin
          Close;
          ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+FileName+ ';Persist Security Info=False';
          CursorType:=ctKeyset;
          SQL.Clear;
          SQL.Text:='select TOP 1 * from memo1 where memodate >= date() and memotype = '''+'0'+''' order by memotime asc';///按照升序法筛选出第一条记录
          Open;
      end;
      if ADOQ.RecordCount>0 then
      begin
        a^[0]:=TimetoStr(ADOQ.Fields[3].Value);
        a^[1]:=DatetoStr(ADOQ.Fields[2].Value);
        a^[2]:=ADOQ.Fields[1].Value;
      end;
      ADOQ.Close;
      ADOQ.Free;
      except
        on E:Exception do
        begin
          showmessage(e.Message);
        end;
      end;
     CoUnInitialize;
    end;