我的一个服务器端程序,用到OleVariant传数据给客户端,10天内可能会有一次报错且是致命的,
  错误内容是‘Read of address 00000001’,一出这个错误,服务器就崩了,其他凡有OleVariant操作的地方,一执行就会报错
  经追踪,发现是给OleVarian变量赋值或执行VarClear时出错
有谁知道为什么会这样呀,帮帮忙呀

解决方案 »

  1.   

    或者说一下OleVariant的内存机制,如何做才能避免这些问题
      

  2.   

    是哦,你是否可以贴出代码?另外,是否可以不要使用VarClear这个函数,自己不要释放他。
      

  3.   

    我的是三层程序,服务器端是Rdm,rdm调用我编写的Dll, dll里面有OleVariant变量的操作的,代码很简单,天天都会执行到它的, OleVariant变量的操作的函数可能会出错,没带OleVariant变量的操作的从来不会出错的
      

  4.   

    没遇到过
    去掉VarClear试试
      

  5.   

    怀疑ole初始化不成功.不过你说的太迷幻,要不帖code吧
      

  6.   

    hehe,楼主怎么找到了我的id发消息了^o^
      

  7.   

    >>有内存泄露,导致耗尽内存 
      应该没有,这时你调用其他函数没带OleVariant变量的又没有问题
      VarClear老出错,但我去掉了,不在这出错了,而又在给OleVariant变量值的地方出错
      

  8.   

    我也怀疑是firetoucher(风焱)的情况,但要如何初始化呢才算正确呢?class function PubDbServer.DataSetToOle(DataSet: TDataSet): OleVariant;
    var
      Dsp: TDatasetProvider;
    begin
      try
        Dsp := TDatasetProvider.Create(nil);
        try
          Dsp.Constraints := false;
          Dsp.Exported := false;
          Dsp.DataSet := DataSet;
          //Dsp.ResolveToDataSet := false;
          Result := Dsp.Data;
        finally
          Dsp.Free;
        end;
      except
      end;
    end;function TWcldDm.ReadClawv(var CORP_ID: String; var OleData: TeOleType): String;
    begin
      try
        //VarClear(OleData); //如果不注释,这里会偶尔出错,跟描述的情况一样
      except
      on e: exception do 
          PubFile.FileWriteLog(ExtractFilePath(ParamStr(0)) + 'eLog\eServerErrLog.Log',
            'DataSetToOle: ' + e.Message, 2500);
      end;
      //从数据库中读取出数据
      Result := TPubSQL.Open(SQLQuery1, 'SELECT CORP_ID, CLD_ID, LAWV_V, ' +
      'LAWV_NOTE, LAWV_TS  FROM PZ_CLAWV WHERE CORP_ID = ' + QuotedStr(Corp_ID));
       if trim(Result) <> '' then exit;
      //数据以OleData形式返回客户端
      OleData := TPubDbServer.DataSetToOle(SQLQuery1);
      SQLQuery1.Close;
    end;
    就是给OleData赋值时出错
      

  9.   

    这种问题,如楼上各DX所说,写出一段代码能重现错误就好调试了。10来天才出一次错,甚至可以怀疑Delphi在处理OleVariant类型存在bug(呵呵,非DX的一贯思维,碰到问题先怪Delphi-_-!!)
      

  10.   

    哈哈,也不全是10天就会出现一次,有时可能是半月,一个月啦,这是大概的时间,不定的
       要是能重现,我可能自己也能搞定了,自己测试一千遍也不会报错,一到客户哪运行一段时间就出错了,最头疼就是这种不知何时何地何原因冒出的东西(明明看着代码是没问题的),很郁闷的
      
      有的时候我也怀疑是Delphi自身的bug
      

  11.   

    function TWcldDm.ReadClawv(var CORP_ID: String; var OleData: TeOleType): String;/////////////////////////////////////////
    TeOleType是个什么类型?
      

  12.   

    >>我的一个服务器端程序,用到OleVariant传数据给客户端
    每次新建一个?? 还是一个全局变量?很多可能,或许第一个,你先检查下内存的情况,看内存会不会逐步增长,内存泄露?再检查,是不是共享冲突的问题>>‘Read of address 00000001’
    好像是还没初始化,或者溢出了
      

  13.   

    class function PubDbServer.DataSetToOle(DataSet: TDataSet): OleVariant;返回值使用OleVariant传递对象作为返回值请使用interface,否则只能作为TPointer传递,作为指针使用,要注意释放对象,但是,通常我们没有释放返回值的习惯,会造成内存泄漏,这种情况下请使用interface返回对象,这样可以自动释放,而且在转换为OleVariant时候可以正确转换。我认为这是一个可能的原因。OLE转换数据的时候需要你自己写程序处理,很多的数据并不能被OLE正确的转换,特别是指针。
      

  14.   

    >>我的一个服务器端程序,用到OleVariant传数据给客户端
    呵呵, 我的只有一个服务器程序
    内存无泄露,我用内存工具检测是过
    我的服务器端是采用线程缓冲池方式,一次测试十几二十个连接也没问题,更多的也没问题,并不是次次都是这样,而是有可能服务器运行一个月才有这种错误情况,要是内存有泄露一天可能就崩了,因为客户那有十几个客户端天天在用的
      

  15.   

    zhangl_cn(不做和尚了!) : 哦,sorry! 
      TeOleType = OleVariant;BlueTrees(蜗牛) : 如果是你所说的情况,我以上的函数应如何改呢?  我试过,直接给OleVariant赋Null值有时也会也错的
      

  16.   

    当年有了类似的问题,折磨了我三个月没睡好,
    不知道是否是同样的情况,你试下用 同步机制 来限制这段写的代码因为我们一般用单cpu,冲突的机会极小,但还是有可能,
    试下看是不是我说的原因
      

  17.   

    如何调用的ReadClawv?如果是多线程的,考虑用临界区保护试试
      

  18.   

    第一,这个函数你封装了一个"哑巴错误"class function PubDbServer.DataSetToOle(DataSet: TDataSet): OleVariant;
    var
      Dsp: TDatasetProvider;
    begin
      try
        Dsp := TDatasetProvider.Create(nil);
        try
          Dsp.Constraints := false;
          Dsp.Exported := false;
          Dsp.DataSet := DataSet;
          //Dsp.ResolveToDataSet := false;
          Result := Dsp.Data;
        finally
          Dsp.Free;
        end;
      except
      end;
    end;
      

  19.   

    第二:
    function TWcldDm.ReadClawv(var CORP_ID: String; var OleData: TeOleType): String;
    begin
      try
        .....
      except
      on e: exception do 
          PubFile.FileWriteLog(ExtractFilePath(ParamStr(0)) + 'eLog\eServerErrLog.Log',
            'DataSetToOle: ' + e.Message, 2500);
         //在Except这段代码里,是没有用try保护住的...不清楚你的FileWriteLog里线程保护了吗?
      end;
      

  20.   

    确实难分析
    但是经验告诉我:WIndows自己也不是非常的稳定可靠的
      

  21.   

    错误是出在
      OleData := TPubDbServer.DataSetToOle(SQLQuery1);//这句的,这句我用try...except end;
    捕捉过,问题的关键不是出现在TPubDbServer.DataSetToOle(SQLQuery1)里面,而是给OleVariant变量赋值时或执行VarClear时会出错
      

  22.   

    其实Result := Dsp.Data;返回的是一个数组,并不是一个对象
      

  23.   

    错误是出在
      OleData := TPubDbServer.DataSetToOle(SQLQuery1);//这句的,这句我用try...except end;
    捕捉过,问题的关键不是出现在TPubDbServer.DataSetToOle(SQLQuery1)里面,而是给OleVariant变量赋值时或执行VarClear时会出错//////////////////////////////////////////////////
    换一下声明试试:function PubDbServer.DataSetToOle(DataSet: TDataSet,out Data:OleVariant): boolean;
      

  24.   

    这样有区别吗,那VarClear出错呢
      

  25.   

    难!
    CarClear执行清理的时候清理过程比较复杂,很难知道是哪一个地方出了问题。
      

  26.   

    并不是每次VarClear都会有问题,并不是每次给OleVariant变量赋值都会有问题,十天半个月偶尔的傻冒个错误给你,哈哈,晕,真是晕晕!!!!!!!!!!!!!!!!!!!!!!!!   还有一点就是,我是在DLL中给OleVariant变量发现有这种问题,在宿主Exe中从没冒过这个错误的,因为OleVariant变量会传到Exe中再返回客户端的
      

  27.   

    合并DLL到Exe中不就解决了,呵呵
      

  28.   

    感觉不是OleVariant本身的错误。还应该在程序的逻辑中来找。
      是不是你的Dsp 返回值有异常的时候。碰巧每隔10天左右就有的用户遇到了。
    或者你这样试一下
      Dsp:= TDatasetProvider.Create(self);
      或直接把DSP放到远程数据模块上,然后再使用,不要手动创建了!
      

  29.   

    l0f(凌风)见到你就可以向你发消息了啦:
      其实程序写法应该没问题,其他不带OleVariant变量返回值从没出现过这个错误,只要一出现这个错误,再调用到带OleVariant变量的函就全都会出错
      

  30.   

    给个馊主意: 如果DLL中没有包含窗体的话,你干脆把服务器端改成COM+应该就不会有那么多问题了。
      

  31.   

    function TEamRunServer.OpenData(strSQL: widestring;
      var OutData: olevariant;var Msg:widestring): boolean;
    begin
       Result:=False;
      try
        adoDataSet.Close;
        adoDataSet.CommandText:=strSQL;
        adoDataSet.Open;
        OutData:=DSPRead.Data;
        adoDataSet.Close;
        Result:=True;
      except
        On E:Exception do Msg:=E.Message;
      end;
    end;
    这是我的,我用了两年多了,系统上线运行到现在,没有遇到你说的那种情况!
      

  32.   

    lwk_hlj(阿凯(学习.net中)) , 我用的dbexpress 中的SQLQuery读取数据,不是你用Ado啦
    还有一点是,我的是dll中,你的是不是呢
      

  33.   

    cncharles(旺仔),还跟操作系统有关系的吗,请详细说明一下
      

  34.   

     回复人:eyoue(海蓝天) ( 一级(初级)) 信誉:100  2006-03-01 11:01:00  得分:0

    lwk_hlj(阿凯(学习.net中)) , 我用的dbexpress 中的SQLQuery读取数据,不是你用Ado啦
    还有一点是,我的是dll中,你的是不是呢
    我用dbexpress也是如上处理,也没有问题,但是,我不会做到dll中的,因为三层服务器放用dll如果做不好,就会出很多问题的,处理起来实在太麻烦了,你可以试一下带包编译一下试试!
      

  35.   

    lwk_hlj(阿凯(学习.net中)) 带什么包,如何编译
      

  36.   

    带上最基本的三个包
    vcl,rtl,vclx在project options 的packages页面上
      

  37.   

    To lwk_hlj(阿凯(学习.net中)),你们现在是用BPL代替DLL吗 
    你所说的带什么包,如何编译,是我的DLL带包编译吗