Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


ID: 16942, Delphi 6 Bugs with TDataSet and Variants

by Manuel Parma Email: Anonymous


TField.GetAsByteArray need initialize result!
Download Details
FTP  download also available
CDN Login Required to Download. (You will be redirected to the login page if you click on the Download Link)
To download this, you must have registered:
A free membership

For Delphi, Version 6.0  to 6.0 349 downloads
Copyright: No significant restrictions


Size: 1,650 bytes
Updated on Wed, 07 Nov 2001 12:13:19 GMT
Originally uploaded on Wed, 07 Nov 2001 12:14:07 GMT
SHA1 Hash: 79A76BC485E8092BD4A9E28FB40657B74154A68A
MD5 Hash: 3CD6F5E1C9D466076ACB3A6733BAE0F2

    Explore the files in this upload

Description
My People were working with DbExpress and copying data between 2
TClientDataSet with routing like:
While not Eof do
for i := 0 to Fieldcount - 1 do
Dest.Field.Value := Src.Field.Value;
...
Classic routine, but this ClientDataSet have a TVarByteField , in 100% of
cases we have Variant is not an array when the routine do "Dest.Field.Value
:= Src.Field.Value;" after a day to search the problem, we found a fail in
Db Unit;
TField.GetAsByteArray: Variant;
TField.GetData(Buffer: Pointer; NativeFormat: Boolean = True): Boolean;
TDataSet.GetFieldData(Field: TField; Buffer: Pointer; NativeFormat:
Boolean): Boolean;
TDataSet.DataConvert(Field: TField; Source, Dest: Pointer;
ToNative: Boolean);
procedure BufferToByteArray(Data: Pointer; DataSize: Integer;
var VarArray: OleVariant);
var
PVarData: Pointer;
begin
VarArray := VarArrayCreate([0, DataSize - 1], varByte);
PVarData := VarArrayLock(VarArray);
try
Move(Data^, PVarData^, DataSize);
finally
VarArrayUnlock(VarArray);
end;
end;

In this last routine VarArray get after VarArrayCreate() a "string Value" :(
then I tried initialize the VarArray in GetAsByteArray , like this:
function TField.GetAsByteArray: Variant;
begin
{##Fix By Manuel Parma and Reinaldo Yañez}
VarClear(Result); {## Add This Line}
if not GetData(@Result, False) then Result := Null;
end;
And work fine!!, so we have more deep in code to localize the error, and
found this:
VarArrayCreate create de array fine but VarArrayCreate return Variant and
VarArray is OleVariant, so Delphi call to
variants.pas
procedure _OleVarFromVar(var Dest: TVarData {OleVariant}; const Source:
TVarData);
this call to
procedure VarArrayCopyForEach(var Dest: TVarData; const Src: TVarData;
AProc: TVarArrayForEach);
var
....
begin
// sanity test
if not VarTypeIsValidElementType(Src.VType) then
VarInvalidOp;

// if the array contains variants then we need to handle the copy
ourself
if (Src.VType and varTypeMask) = varVariant then
begin
...
...
end
// array of something other than a variant, just copy it
else
begin
VariantCopy(Dest, Src); {<= this line is the problem}
end;

end;
Variant Copy Returns HRESULT with Error but this code dont' take control of
that! :((
We Change this code with

{We add the next lines}
r := VariantCopy(Dest, Src);
if r <> 0 then
begin
rr := 'Unknown Variant Error';
case r of
HRESULT($8002000D): rr := 'The variant contains an array that is
locked.';
HRESULT($80020008): rr := 'The source and destination have an
invalid variant type '
+ (usually uninitialized).';
HRESULT($8007000E): rr := 'Memory could not be allocated for the
copy.';
HRESULT($80070057): rr := 'The argument pvargSrc was VT_BYREF.';
end;
raise Exception.Create(rr);
end;
And we found
HRESULT($80020008): rr := 'The source and destination have an invalid
variant type '
+ (usually uninitialized).';
So the fix is correct and maybe delphi need change the last code to take
care about this errors in api!

Manuel Parma

For more information, see mparma@usa.net

   Latest Comments  View All Add New

Move mouse over comment to see the full text

Could not retrieve comments. Please try again later.

Server Response from: ETNACDC03