代码基本上是一样的,直接写就出错;把代码写成过程调用就可以,怪了//出错代码:
procedure TForm1.btn3Click(Sender: TObject);
var
MS:TMemoryStream;
P:Pointer;
begin
MS:=TMemoryStream.Create;
try
P:=VarArrayLock(TCustomClientDataSet(ds1.DataSet).Data);
try
MS.Write(P^,VarArrayHighBound(TCustomClientDataSet(ds1.DataSet).Data,1)+1)
finally
//*******这里出错****************
//Variant of safe array is locked
VarArrayUnlock(TCustomClientDataSet(ds1.DataSet).Data);
end;
MS.SaveToFile(ExtractFilePath(ParamStr(0))+'Rec.dat');
finally
FreeAndNil(MS);
end;
end;//可以正常使用的代码
procedure TForm1.btn3Click(Sender: TObject);
var
MS:TMemoryStream;
begin
TCustomClientDataSet(ds1.DataSet).LogChanges:=False;
MS:=TMemoryStream.Create;
try
//*************************************
//这样可以:
VariantToStream(TCustomClientDataSet(ds1.DataSet).Data,MS);
MS.SaveToFile(ExtractFilePath(ParamStr(0))+'Rec.dat');
finally
FreeAndNil(MS);
end;
end;//附上转换过程:
procedure VariantToStream(const Data:OleVariant;Stream:TStream);
var
P:Pointer;
begin
P:=VarArrayLock(Data);
try
Stream.Write(P^,VarArrayHighBound(Data,1)+1);
finally
VarArrayUnlock(Data);
end;
end;
procedure TForm1.btn3Click(Sender: TObject);
var
MS:TMemoryStream;
P:Pointer;
begin
MS:=TMemoryStream.Create;
try
P:=VarArrayLock(TCustomClientDataSet(ds1.DataSet).Data);
try
MS.Write(P^,VarArrayHighBound(TCustomClientDataSet(ds1.DataSet).Data,1)+1)
finally
//*******这里出错****************
//Variant of safe array is locked
VarArrayUnlock(TCustomClientDataSet(ds1.DataSet).Data);
end;
MS.SaveToFile(ExtractFilePath(ParamStr(0))+'Rec.dat');
finally
FreeAndNil(MS);
end;
end;//可以正常使用的代码
procedure TForm1.btn3Click(Sender: TObject);
var
MS:TMemoryStream;
begin
TCustomClientDataSet(ds1.DataSet).LogChanges:=False;
MS:=TMemoryStream.Create;
try
//*************************************
//这样可以:
VariantToStream(TCustomClientDataSet(ds1.DataSet).Data,MS);
MS.SaveToFile(ExtractFilePath(ParamStr(0))+'Rec.dat');
finally
FreeAndNil(MS);
end;
end;//附上转换过程:
procedure VariantToStream(const Data:OleVariant;Stream:TStream);
var
P:Pointer;
begin
P:=VarArrayLock(Data);
try
Stream.Write(P^,VarArrayHighBound(Data,1)+1);
finally
VarArrayUnlock(Data);
end;
end;
procedure TForm1.btn5Click(Sender: TObject);
var
MS:TMemoryStream;
P:Pointer;
begin
MS:=TMemoryStream.Create;
try
P:=VarArrayLock(cds1.Data);
try
MS.Write(P^,VarArrayHighBound(cds1.Data,1)+1)
finally
//*******这里出错****************
//Variant of safe array is locked
VarArrayUnlock(cds1.Data);
end;
MS.SaveToFile(ExtractFilePath(ParamStr(0))+'Rec.dat');
finally
FreeAndNil(MS);
end;
end;
procedure TForm1.btn5Click(Sender: TObject);
var
v:Variant;
begin
V:=cds1.Data;
Caption:=IntToHex(Integer(@V),8);
V:=cds1.Data;
Caption:=Caption+':'+IntToHex(Integer(@V),8);
end;
VarArrayLock(TCustomClientDataSet(ds1.DataSet).Data);
VarArrayUnlock(TCustomClientDataSet(ds1.DataSet).Data);
代码2:
const Data:OleVariant;
Data = TCustomClientDataSet(ds1.DataSet).Data ;
VarArrayLock(Data);
VarArrayUnlock(Data);
//这两段代码是不一样的。
属性Data , 类型是OleVariant . 取属性时,会生成一个临时对象 OleVariant .
VarArrayLock 一个临时OleVariant对象,然后被释放,这没有影响,但随后VarArrayUnlock一个没有被Lock的临时对象就出错了。中间用一个Data将属性值复制出来后,就没有这个问题。BCB的代码,会很清楚地知道是指针还是引用还是对象。而delphi代码则要依据对象的性质来决定是指针还是对象。对象的生命期特性没有CB代码那么明确。我试图这样解析,再静听后面高人讲解。