Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.10;
Скачать: CL | DM;

Вниз

Access violation при освобождении Variant.   Найти похожие ветки 

 
Erik ©   (2004-01-30 12:35) [0]

Я тут немного поэсперементировал и написал волее оптимальный преобразовалель record в variant и обратно. Но при востановлении record происходит Access violation. Сейчас тестирую, но еще непонял где ошибка.
procedure DataToVariant1(Const Params: PRTKParams; Var VData: OleVariant);
Var
RecSize, SizeArray: Word;
PData: PByteArray;
i, SizeMem, ArrByteSize, SizeStn: Integer;
begin
RecSize := SizeOf(Params^);
SizeMem := Sizeof(RecSize);

ArrByteSize := GetByteSizeArr(@Params.TeenID, SizeArray);
SizeMem := SizeMem + ArrByteSize + SizeOf(SizeArray);
SizeStn := RecSize-SizeOf(Params^.TeenID);
SizeMem := SizeMem + SizeStn;

VData := VarArrayCreate([0, SizeMem],varByte);
PData := VarArrayLock(VData);
try
i := 0;
MoveREx(@RecSize, PData, i, SizeOf(RecSize));
MoveREx(@SizeArray, PData, i, SizeOf(SizeArray));
MoveREx(@Params.TeenID[0], PData, i, ArrByteSize);
MoveREx(@Params^, PData, i, SizeStn);
finally
VarArrayUnLock(VData);
end;
end;

procedure VariantToData1(const VData: OleVariant; Const Params: PRTKParams);
Var
RecSize, ArraySize: Word;
SizeStn, ByteArraySize, i: Integer;
PData: PByteArray;
begin
FillChar(Params^, SizeOf(Params^), 0);
PData := VarArrayLock(VData);
try
i := 0;
MoveEx(PData, @RecSize, i, SizeOf(RecSize));
if RecSize <> SizeOf(Params^) then
raise Exception.Create("Error size PRTKParams in VariantToData");

SizeStn := RecSize-SizeOf(Params^.TeenID);
MoveEx(PData, @ArraySize, i, SizeOf(ArraySize));
SetLength(Params.TeenID, ArraySize);
ByteArraySize := GetByteSizeArr(@Params.TeenID, ArraySize);
MoveEx(PData, @Params.TeenID[0], i, ByteArraySize);
MoveEx(PData, @Params, i, SizeStn);
finally
VarArrayUnLock(VData); //- здесь Access violation
end;

end;
Это вспомогательные процедуры
procedure MoveEx(const P1, P2: PByteArray; var Index: Integer; Size: Integer);
begin
Move(P1^[Index], P2^, Size);
Inc(Index, Size);
end;

procedure MoveREx(const P1, P2: PByteArray; var Index: Integer; Size: Integer);
begin
Move(P1^, P2^[Index], Size);
Inc(Index, Size);
end;


 
alex_*** ©   (2004-01-30 14:12) [1]

Лень было в твоем коде разбираться, нбросал свой - вроде работает.

Проверь что у тебя в record не входят длинные строки и ссылки на объекты.


procedure TMainGetFrm.PackRec;
type
TRec = record
mas: array[0..20] of char;
ID: Integer;
STATUS: Integer;
end;

function Pack(rec: TRec):Variant;
var p:Pointer;
Begin
result := VarArrayCreate([0,sizeof(TRec)-1],varByte);
p := VarArrayLock(result);
try
CopyMemory(p,@rec,sizeof(rec));
finally
VarArrayUnlock(result);
end;
End;

function UnPack(var v: Variant): TRec;
var p:Pointer;
Begin
Assert(VarArrayHighBound(v,1)+1=sizeof(TRec),Format("%d<>%d",[VarArrayHighBound(v,1)+1,sizeof(TRec)]));
p := VarArrayLock(v);
try
CopyMemory(@result,p,sizeof(TRec));
finally
VarArrayUnlock(v);
end;
End;
var r: TRec;
v: Variant;
begin
ZeroMemory(@r,sizeof(r));
StrCopy(@r.mas[0],"testing");
r.ID := 667;
r.Status := 889;
v:=Pack(r);
ZeroMemory(@r,sizeof(r));
r := UnPack(v);
ShowMessage(
"mas: "+String(r.mas)+#13+
"ID: "+IntToStr(r.ID)+#13+
"STATUS: "+IntToStr(r.Status)
);
end;


 
Тимохов ©   (2004-01-30 14:17) [2]


> Проверь что у тебя в record не входят длинные строки и ссылки
> на объекты.

А также динамические массивы и интерфейсы.


 
Erik ©   (2004-01-30 14:25) [3]

Вопрос решон, ошибся я слегка запхивая сначала динамический масив а затем основной record. Надо было наоборот. Вся суть в том, что передаются разнородные данные.
Тимохов
Динамические масибы разумеется входят, но проблем с их передачей нет. Строки тоже передавал.
Это то, что я передаю.
WorkType = (wtUhendus, wtLulitus, wtHooldus, wtVolg);
TArrayID = packed Array of Integer;
PArrayID = ^TArrayID;
RTKParams = packed record
Kuupaev : Integer; //TDateTime;
Aeg : Integer;
TkAeg : Integer; //Size Time
VAegID : Integer;
Size: Integer;
ReservID: Cardinal;
TkID: Integer;
TkLiik: WorkType;
TeenID: TArrayID; //Last element structure
end;
PRTKParams = ^RTKParams;
Всем большое спасибо за внимание. У меня так бывает сночала вроде неясно в чем проблема, а после задания вопроса все становится ясно. :)


 
alex_*** ©   (2004-01-30 14:28) [4]

ссылочные объекты внимательнее передавай - чтоб передавалась копия объекта а не ссылка на него. Хотя это может и не важно для тебя.


 
Тимохов ©   (2004-01-30 14:55) [5]

Чтобы заниматься копированием по средством премещения памяти (командой move) строк и дин массивов, надо очень хорошо представлять как они устроены. Если у тебя все рабоатает, то очень хорошо. Но дорожка, как говорил, если не ошибась всеча Digitman, кривовата...

Делать move записи, которая сожержит дин массив так как делаешь ты нельяз - нарушается подстчет ссылок на этот массив.


 
Erik ©   (2004-01-30 15:56) [6]

Я же просто попирую иформацию в буфер, нетрогая масива. А после законно востанавливаю масив командой SetLength. Так, что вроде впорядке?



Страницы: 1 вся ветка

Текущий архив: 2004.02.10;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.021 c
11-29291
acp
2003-05-26 23:32
2004.02.10
TBitmap не хочет сохранять картинку


7-29642
Mr.Nobody
2003-11-25 22:17
2004.02.10
Чтение из com-порта...


3-29205
Pako
2004-01-20 08:40
2004.02.10
Select


1-29413
Maxim Vetera
2004-01-31 20:30
2004.02.10
2 динамических массива в 1


3-29233
Vitalik
2004-01-19 14:30
2004.02.10
Добавление строк в таблицу ч/з DBGrid