Форум: "Основная";
Текущий архив: 2004.02.10;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.008 c