procedure TForm1.btn1Click(Sender: TObject);
var
  ts:TStrings;
begin
  ts:=TStringList.Create;
  qry1.GetFieldNames(ts);//qry1为TADOQuery
  ShowMessage(ts.CommaText);
  ts.Free;
end;
以上代码在Exe里运行无错procedure Test(qry1:TDataSet);
var
  ts:TStrings;
begin
  ts:=TStringList.Create;//或ts:=TFieldList.Create(qry1);
  qry1.GetFieldNames(ts);
  ShowMessage(ts.CommaText);
  ts.Free;
end;
exports
   Test;这段代码放在动态库中却报错。
不知是为什么?怎么解决?

解决方案 »

  1.   

    你的动态库里定义qry1这个东东了么
      

  2.   

    报TFieldList不能转换成TStringList;
    源代码错误行在delphi的db.pas里。具体的为List.Assign(F....);
      

  3.   

    >>procedure Test(qry1:TDataSet);
    dll傳遞實例, 并不安全!
      

  4.   

    放在单独的单元中当然没问题,你放在dll里,然后写个exe调一下试试
      

  5.   

    to aiirii:不安全但是不应该出错吧
      

  6.   

    这样吧,你传TStrings进去procedure Test(qry1:TDataSet;ts:TStrings);stdcall;
    //var
    //  ts:TFieldList;
    begin
      //ts:=TFieldList.Create(qry1);//或ts:=TFieldList.Create(qry1);
      qry1.GetFieldNames(ts);
      ShowMessage(ts.CommaText);
      ts.Free;
    end;exports
       Test;var
        ts : TStrings;
    begin
        ts := TStringList.Create;
        Test(adoquery1, ts);
    end;
      

  7.   

    传TStrings进去是可以。不过为什么在dll里面建个TStrings就不行了。
    而且现在关键是调用TDataSet.GetFieldNames的代码是在第三方组件里。那个TStringList不是我传进去的,是组件内部自己的。
    有什么办法可以让他不报错。
      

  8.   

    就象如下例子调用FastReportprocedure Test(AOwner:TCustomForm;qry1:TDataSet);
    var
      frx:TfrxDBDataset;
      frxReport1:TfrxReport;
    begin
      frxReport1:=TfrxReport.Create(AOwner);
      frx:=TfrxDBDataset.Create(AOwner);
      frx.Name:='frxDBDataset1';
      frx.UserName:='frxDBDataset1';
      frx.DataSet:=qry1;
      frxReport1.DataSet:=frx;
      frxReport1.LoadFromFile('D:\test.fr3');
      if frxReport1.PrepareReport() then
      frxReport1.ShowReport();
      frx.Free;
      frxReport1.Free;
    end;在frxReport1.PrepareReport()时,FastReport会去调DB.pas里的GetFieldNames,你说TStrings怎么传进去?
      

  9.   

    控件与DLL不同
    我的理解,控件跟你的EXE是的一个整体,而DLL是调用外部的接口!
    控件可以不说明DLL就可以。。就是你上面说的为什么在EXE里可以,在DLL里不行
      

  10.   

    我在dll里调PrePareReport()里为什么就报错。我全是动态生成的。
    同一段代码copy到Exe里就一点错都没有?
      

  11.   

    这一点我也不清楚,可能DLL的数据定义规则跟EXE有差别吧!
      

  12.   

    兄弟,有QQ吗?QQ聊方便。7148668加我
      

  13.   

    你把ShowMessage(ts.CommaText);去掉呢?不清楚你的其他代码是什么。
    呆会发个文章,你看看有没有启发。一般实在找不到原因,可以考虑showmessage的问题
      

  14.   

    在调试程序时,特别是对于初编写程序经验不足的初手来说,代码检查通过却总得不到预期的结果不能不算作一桩令人头痛的事情,它可能会耗费你比编写程序还要大几倍的精力去检查逻辑错误的所在并修正它,然而程序时不时地得到正确的结果却比总得不到正确的结果还要可恶,因为并不丰富的经验很难判断出到底是什么因素导致的结果出错:是逻辑错误,还是程序之外的其他环境所至?
    前不久为一个模拟股市比赛写了个交易系统,经过谨慎测试后才交付使用,在比赛正式举行时,却很出乎意料的发生了有几个帐户的数据发生了严重的混乱:一个帐户资金出现负数,一个帐户股票持量出现负数,另外一些帐户所挂的交易单明明符合交易条件却没有成交,
    当日比赛后,检查了n遍源代码都找不到原因,代码中当资金不足或股票持量不足时是不可能执行交易的,怎么可能会有负数;而本应成交却未成交就更莫名其妙,交易单是按照委托价格的顺序进入队列,不可能出现有两个价位成交而介于这两个价位之间的价位却没有成交的情况。一切错误都与规定交易规则的代码明显冲突,百思不得其解,在不解的状态下模拟
    交易的数据测试,居然结果时对时错,且无规律可循,就更加疑惑了:没有随机函数之类的调用,又确定不可能有溢出,为什么会时对时错?
    一遍又一遍地看代码、输数据,实在不知道该怎么办,眼睛停在显屏上,突然看到DBGrid中的记录位置动了一下,疑神片刻,恍然小悟,赶紧翻开两段代码:
    procedure TFrm_option.Timer2Timer(Sender: TObject);
    var
    i:integer;
    myfstream:Tfilestream;
    begin
    table1.Active:=false;
      table2.active:=false;
      table3.Active:=false;
    //备份数据表文件的代码
    ·
      ·
      ·
      table1.Active:=true;
      table2.Active:=true;
      table3.Active:=true;
    end;procedure TFrm_option.Button1Click(Sender: TObject);
    var s,m,q,temp_min,flag:integer;
     n,p:single;
     pricestr:string;
    begin
     ·
      ·
      ·
    with table3 do  //定位记录、检查并设定活动资金是否足够
      begin
       setkey;
       fieldbyname('号码').AsInteger:=table1['客户代码'];
       gotokey;
      end;
      table3.Edit;
      table3[‘活动资金’]:=table3[‘活动资金’]-table1[‘价格’]*table1[‘数量’];
      table3.Post;
    ·
      ·
      ·
      showmessage('卖单号:'+inttostr(table2['卖单号']));
    ·
      ·
      ·
      table3.Edit;        
      //执行交易的代码,;
      table3.post;
    end;
    第一个过程是起每五秒备份数据表文件的作用,第二个过程则具体执行交易更新数据表数据,之前检查代码确实很难留意把这两个过程联系一起分析,而问题就恰恰出在计时器和第二个过程的showmessage()函数上,这个showmessage()函数用来告之输入者程序分配给他委托的交易的流水号,一般就被看一眼一带而过,而假如他要记下这个号码而并不很快关掉这个消息框,程序就处于中断而等待消息框“确定”被点击状态,一旦等待时Timer2的Ontime事件被触发,那就惨了:Table1、Table2、Table3被关闭再打开,记录位置便到了首记录,而在第2个过程中showmessage()函数之前有一段定位要修改数据的记录,而之后便是修改数据的代码,消息框打开时一旦ontime事件被触发,消息框关闭后修改的数据便是首记录的数据而非所定位的应该修改数据的记录了。所以,当客户因为用笔在纸上记下号码或做其他的事情而不在下一ontime事件触发之前关掉消息框,遍产生了错误,这个在非所对应的记录上更新数据也正是开始所述的资金、持股量出现负数、成交价位出错和后来测试时结果时对时错的原因所在。
    所以,无论是在程序编写还是程序检查时,一定要留意消息框开启的时间也是要算到一个执行过程的执行时间中的,而我当初很谨慎的测试程序时,忽略了这一点——测试程序时没必要去记下消息框的内容,于是总立刻关掉消息框,此间并没有ontime事件的触发,进而每次得到的结果都是对的,全然不知留下了这个bug;而出错之后检查,会偶尔有消息框打开时在思考问题的情形发生,便导致了偶尔出错的发生。
    Showmessage(),只是启发我想到这个问题。在程序编写时,如果用到计时器控件或计时性的代码,一定要谨慎考虑周全相关单元文件中影响时间的所有因素,代码的效率影响执行时间是比较容易联想到的因素,然showmessage()函数这类时间上受人为控制的因素也不能忽略。而程序运行后如结果不规律的出现错误,也不妨考虑一下这一点。
      

  15.   

    to aiirii:不安全但是不应该出错吧
     不安全, 就有可能出錯的, dll 與 exe 的內存空間還有些差別, 直接傳對象, 結果不一定正确