Dll部分代码
function GetDataSet(str,conn:PChar):TADODataSet;stdcall;

function GetDataSet(str,conn:PChar): TADODataSet;stdcall;
var
  ds:TADODataSet;
begin
  //coInitialize(nil);
  ds:=TADODataSet.Create(nil);
  ds.Close;
  ds.ConnectionString:=conn;
  ds.CommandText:= str;  try
      ds.Open;
      GetDataSet:=ds;
      //StrDispose(str);
  except
     on E:Exception do
     begin
        ShowMessage(E.Message);
        GetDataSet:=nil;
     end;
  end;
  //CoUninitialize;
end;initialization;
begin
   CoInitialize(nil);//创建
end;
finalization;
begin
  CoUninitialize;
end;
调用部分
var
  datas:TADODataSet;
  sql,conn:string;
  i:Integer;
begin
   sql:='select GrCode from ZwGrml';
   conn:='Provider=SQLOLEDB.1;Password=sa;Persist Security Info=True;User ID=sa;Initial Catalog=HNR_Data_2008';
    datas:=GetDataSet(PChar(sql),PChar(conn));
     try
         DBGridEh1.DataSource.DataSet:=datas;
     except
      on E:Exception do
      begin
         ShowMessage(E.Message);
      end;
   end;
补充 我用
for i := 1 to datas.RecordCount do
   begin
     datas.RecNo:=i;
     Memo1.Lines.Add(datas.FieldByName('GrCode').AsString);
   end;
往Memo1里添加数据正常!!但是往DBGridEh1 或是DBGrid1 里填充就提示错误了!提示invalid pointer operation  无效类型指针!!不知道为什么!

解决方案 »

  1.   

    不应该出现这样的设计,最起码应该这样:procedure GetDataSet(str,conn:PChar; ds: TADODataSet);stdcall; 
    procedure GetDataSet(str,conn:PChar; ds: TADODataSet);stdcall; 
    begin 
      ds.Close; 
      ds.ConnectionString:=conn; 
      ds.CommandText:= str; 
      ds.Open; 
      end; 
    end; initialization; 
    begin 
      CoInitialize(nil);//创建 
    end; 
    finalization; 
    begin 
      CoUninitialize; 
    end; 
    调用部分 
    var 
      datas:TADODataSet; // 应该放到private部分
      sql,conn:string; 
      i:Integer; 
    begin
      datas := TADODataSet.Create(nil);
      sql:='select GrCode from ZwGrml'; 
      conn:='Provider=SQLOLEDB.1;Password=sa;Persist Security Info=True;User ID=sa;Initial Catalog=HNR_Data_2008'; 
        datas:=GetDataSet(PChar(sql),PChar(conn), datas );
        DBGridEh1.DataSource.DataSet:=datas; 
      end; 
      

  2.   


    procedure GetDataSet(str,conn:PChar; ds: TADODataSet);stdcall; 
    procedure GetDataSet(str,conn:PChar; ds: TADODataSet);stdcall; 
    begin 
      ds.Close; 
      ds.ConnectionString:=conn; 
      ds.CommandText:= str; 
      ds.Open; 
    end; initialization; 
    begin 
      CoInitialize(nil);//创建 
    end; 
    finalization; 
    begin 
      CoUninitialize; 
    end; 
    调用部分 
    var 
      datas:TADODataSet; // 应该放到private部分
      sql,conn:string; 
      i:Integer; 
    begin
      datas := TADODataSet.Create(nil); // 应该放到FormCreate部分 // Destroy释放
      sql:='select GrCode from ZwGrml'; 
      conn:='Provider=SQLOLEDB.1;Password=sa;Persist Security Info=True;User ID=sa;Initial Catalog=HNR_Data_2008'; 
        datas:=GetDataSet(PChar(sql),PChar(conn), datas );
        DBGridEh1.DataSource.DataSet:=datas; 
      end; 
      

  3.   

    在网吧写的,比较乱......procedure GetDataSet(str,conn:PChar; ds: TADODataSet);stdcall; 
    procedure GetDataSet(str,conn:PChar; ds: TADODataSet);stdcall; 
    begin 
      ds.Close; 
      ds.ConnectionString:=conn; 
      ds.CommandText:= str; 
      ds.Open; 
    end; initialization; 
    begin 
      CoInitialize(nil);//创建 
    end; 
    finalization; 
    begin 
      CoUninitialize; 
    end; 
    调用部分 
    var 
      datas:TADODataSet; // 应该放到private部分
      sql,conn:string; 
      i:Integer; 
    begin
      datas := TADODataSet.Create(nil); // 应该放到Form.onCreate部分 // form.onDestroy释放
      sql:='select GrCode from ZwGrml'; 
      conn:='Provider=SQLOLEDB.1;Password=sa;Persist Security Info=True;User ID=sa;Initial Catalog=HNR_Data_2008'; 
        GetDataSet(PChar(sql),PChar(conn), datas );
        DBGridEh1.DataSource.DataSet:=datas; 
      end; 
      

  4.   

    非常感谢qiume !按您的方法,可以使用了!
    但是我想问一下!为什么 得传ADODateSat进去才不会出错呢!
      

  5.   

    1.你的程序返回DataSet时是以函数返回值的形式返回的
    DBGridEh1.DataSource.DataSet:=datas;
    当调用完毕dll后,dll的内存管理器要清理函数的栈信息,这时datas已经被清除了,而主调程序中的DBGridEh1.DataSource.DataSet使用的是一个无效的指针!
    2.
    Memo1.Lines.Add()这时Add内添加的数据是一份值拷贝,即便dll内的值被释放也不影响