Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.009 c
14-29613
Думкин
2004-01-19 06:14
2004.02.10
С днем рождения! 19 января.


1-29331
Anton.
2004-01-29 17:40
2004.02.10
Handle


1-29378
DelphiNew
2004-01-29 09:24
2004.02.10
ListBox


14-29588
Ig
2004-01-20 00:20
2004.02.10
Как в строковом массиве определить длину?


3-29267
Rimd
2004-01-18 09:24
2004.02.10
InterBase





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский