unit Unit2;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
const    SIZE_REPEAT_QUEUE               =       10;                //接受缓冲区大小
    SIZE_DATA_RESULT                =       16384;              //接受缓冲区大小    WRITE_EEROR                     =       -1;                 //已满
    READ_EEROR                      =       -2;                 //已空
    WR_OK                           =       1;                  //写读成功
type
     //
  TREPEATBUFFER = record
     buffer: array [0..(SIZE_REPEAT_QUEUE-1),0..(SIZE_DATA_RESULT-1)] of Byte;  //buf
     proIndex: Integer;                         //
     conIndex: Integer;                         //
  end;   //保存比较信息
  TLABELRESULT = record
     stdLabelX: Double;                         //标准宽度
     msrLabelX: Double;                         //测量宽度
     stdLabelY: Double ;                        //标准厚度
     msrLabelY: Double;                         //测量厚度
     stdLabelArea: Double;                      //标准面积
     msrLabelArea:Double;                       //测量面积
  end;  TArrayDouble=array of Double ;    //要保存的数据结果
  PPTDATARESULT=^TDATARESULT;
  TDATARESULT = record
     measureType:Integer;                       //测量类型
     userName: string;                          //用户名
     productName: string ;                      //产品名
     msrOrigin: integer;                        //原点
     flagCPK: integer;                          //标志位
     msrThickness: array of Double;             //测量数据
     mTLABELRESULT:array of TLABELRESULT;       //较结果
  end;  function WriteData(var pTREPEATBUFFER:TREPEATBUFFER; var pTDATARESULT :TDATARESULT ):Integer;
  function ReadData(var pTREPEATBUFFER:TREPEATBUFFER; var pTDATARESULT :TDATARESULT):Integer;var    mTDATARESULT:TDATARESULT;       //
    
    msTDATARESULT:TDATARESULT;      //    mTREPEATBUFFER:TREPEATBUFFER;   //implementation //将数据结果写入buf
    function WriteData(var pTREPEATBUFFER:TREPEATBUFFER; var pTDATARESULT :TDATARESULT ):Integer;
    var
        dst:PByte;
        src,a:Pointer;
    begin
        try
            dst:=nil;
            src:=nil;
            if ((pTREPEATBUFFER.proIndex+1) mod SIZE_REPEAT_QUEUE) =pTREPEATBUFFER.conIndex then
            begin
                Result:=WRITE_EEROR;
                Exit;
            end;
            dst:[email protected][0];
            src:=@pTDATARESULT;
            Inc(dst,pTREPEATBUFFER.proIndex*SIZE_DATA_RESULT);
            a:=dst;
            CopyMemory(dst,src,SIZE_DATA_RESULT);
            pTREPEATBUFFER.proIndex :=(pTREPEATBUFFER.proIndex +1) mod SIZE_REPEAT_QUEUE;            Result:=WR_OK;
        finally
            //Dispose(src);
        end;
    end;    //从buf取数据结果
    function ReadData(var pTREPEATBUFFER:TREPEATBUFFER; var pTDATARESULT :TDATARESULT):Integer;
    var
        dst:Pointer;
        src:PByte;
    begin
        try
            dst:=nil;
            src:=nil;
            //New(pTDATARESULT);
            if pTREPEATBUFFER.conIndex =pTREPEATBUFFER.proIndex then
            begin
                Result:=READ_EEROR;
                Exit;
            end;
            src:[email protected][0];
            dst:=@pTDATARESULT;
            Inc(src,pTREPEATBUFFER.conIndex*SIZE_DATA_RESULT);            CopyMemory(dst,src,SIZE_DATA_RESULT);
            pTREPEATBUFFER.conIndex :=(pTREPEATBUFFER.conIndex +1) mod SIZE_REPEAT_QUEUE;
            Result:=WR_OK;
        finally
            //Dispose(a);
        end;
    end;
end.
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,Unit2 ;
const
    SIZE_RECEIVE_DATA               =       16384;              //接受缓冲区大小
    SIZE_REPEAT_QUEUE               =       128;                //接受缓冲区大小
    SIZE_DATA_RESULT                =       16384;              //接受缓冲区大小
type
     //要保存的数据结果
  TREPEATBUFFER = record
     buffer: array [0..(SIZE_REPEAT_QUEUE-1),0..(SIZE_DATA_RESULT-1)] of Byte;  //数据
     proIndex: Integer;                         //生产指针
     conIndex: Integer;                         //消费指针
  end;    //要保存的数据结果
  PPTDATARESULT=^TDATARESULT;
  TDATARESULT = record
     measureType:Integer;                       //测量类型,0为胎面,1为左胎侧,2为右胎侧
     //msrThickness: TArrayDouble;                //测量厚度数据
     userName: string;                          //用户名
     productName: string ;                      //产品名
     msrOrigin: integer;                        //测量曲线的原点
     flagCPK: integer;                          //CPK标志位
     //mTLABELRESULT:array of TLABELRESULT;       //标注点比较结果
  end;
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
    i,len:Integer;
    a,b,c,d:Pointer;
begin    //A 段代码
    {SetLength(mTDATARESULT.msrThickness,1000);
    for i:=0 to High(mTDATARESULT.msrThickness) do
    begin
        mTDATARESULT.msrThickness[i]:=(i+1)*0.0292;
    end;}
    //B 段代码
    SetLength(mTDATARESULT.mTLABELRESULT,10);
    for i:=0 to High(mTDATARESULT.mTLABELRESULT) do
    begin
        mTDATARESULT.mTLABELRESULT[i].stdLabelX :=(i+1)*0.123;
        mTDATARESULT.mTLABELRESULT[i].msrLabelX  :=(i+1)*0.42;
        mTDATARESULT.mTLABELRESULT[i].stdLabelY :=(i+1)*0.312;
        mTDATARESULT.mTLABELRESULT[i].msrLabelY  :=(i+1)*0.622;
        mTDATARESULT.mTLABELRESULT[i].stdLabelArea  :=(i+1)*0.674;
        mTDATARESULT.mTLABELRESULT[i].msrLabelArea  :=(i+1)*0.754;
    end;    //C 段代码
    mTDATARESULT.measureType :=9;
    mTDATARESULT.userName :='I love learning';
    mTDATARESULT.productName :='LOVE';
    mTDATARESULT.msrOrigin :=9527;
    mTDATARESULT.flagCPK :=1;
    //D 段代码
    WriteData(mTREPEATBUFFER,mTDATARESULT);
    ReadData(mTREPEATBUFFER,msTDATARESULT);end;
end.
    建立一个工程,新建一个窗体Form1,在窗体上添加一个按钮,原代码如上,有两个Unit,Unit1是窗体代码,Unit2 是另一单元代码,然后是 Unit1 调用 Unit2 的函数,但是出现以下问题:(看 Unit1 的按钮事件,有四段代码)
    A:如果按着现在代码不动,直接运行,点击按钮,然后关闭窗体,则正常退出,无任何错误;此时,将B段数组长度加大,如加到 100 ,然后运行程序,点击按钮,再关闭窗体,此时就会报错;
    B: 如果屏蔽掉B段代码,打开A段代码,按着A的操作过程重走一遍,结果也会报错;
    C:如果屏蔽掉C段代码,打开A和B段代码,如果两个数组不是很大,则不会报错,若是其中一个很大,则会报错;   请各位前辈们帮忙,小弟第一次使用这Delphi,更是第一次使用这一个函数,此问题很急,望前辈们帮帮这小忙!此程序目的是将数据结果先放到buf暂存起来,然后别地方要用时,再从buf中取出来。

解决方案 »

  1.   

    是因为你的结构体定义有问题,将下面的结构体里面的string类型改为char类型就不出错了
    PPTDATARESULT=^TDATARESULT;
      TDATARESULT = record
      measureType:Integer; //测量类型
      userName: string; //用户名
      productName: string ; //产品名
      msrOrigin: integer; //原点
      flagCPK: integer; //标志位
      msrThickness: array of Double; //测量数据
      mTLABELRESULT:array of TLABELRESULT; //较结果
      end;
    改成:
      PPTDATARESULT=^TDATARESULT;
      TDATARESULT = record
        measureType:Integer; //测量类型
        userName: array[0..31] of char; //用户名
        productName: array[0..31] of char ; //产品名
        msrOrigin: integer; //原点
        flagCPK: integer; //标志位
        msrThickness: array of Double; //测量数据
        mTLABELRESULT:array of TLABELRESULT; //较结果
      end;