![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Variant и Int64
GrBob © (2006-08-17 14:27:00)Есть такой код:
procedure Proc;
var
A, B: Variant;
begin
A := Int64(10);
B := True;
A := B;
end;
В Win 2003 Server все работает как надо, а вот в 2000 падает с ошибкой "Invalid Variant Type". Кто-нибудь знает почему?
GrBob (2006-08-24 16:16:00) [1]Снова всем привет. Теперь возник такой вопрос: А можно ли вобще иметь вариантный массив of int64?
TArray = array of Int64;
---
FLine: array of TArray;
Result: TArray;
Var: Variant;
---
SetLength(Result, Index);
for I := 0 to Index - 1 do
Result[I] := FLine[Index - 1, I];
----
Var := Result;
Падает на присваивании :(
Anatoly Podgoretsky (2006-08-17 19:05:00) [2]DiamondShark © (17.08.06 16:30) [28]
И побольше
Ketmar (2006-08-17 16:58:00) [3]> [30] DiamondShark © (17.08.06 16:40)
как я сразу и предполагал. ай да я, ай да умник! %-)
DiamondShark (2006-08-17 16:40:00) [4]Ага.
Для VT_I8 мы попадём сюда:
// finally let the OS attempt to deal with it
else
VarResultCheck(VariantClear(V));
;-)
Всё понятно.
clickmaker (2006-08-17 16:33:00) [5]procedure VarCopyDeep(var Dest: TVarData; const Source: TVarData);
var
LSourceHandler: TCustomVariantType;
begin
// clear the destination if needed
if (Dest.VType and varDeepData) <> 0 then
VarClearDeep(Dest);
// take care of the other simple ones
if Source.VType < varInt64 then
VarResultCheck(VariantCopy(Dest, Source))
// Pascal string
else if Source.VType = varString then
begin
Dest.VType := varString;
Dest.VString := nil;
String(Dest.VString) := String(Source.VString);
end
// CORBA Any
else if Source.VType = varAny then
begin
Dest.VType := Source.VType;
Dest.VAny := Source.VAny;
RefAnyProc(Dest);
end
// arrays?
else if Source.VType and varArray <> 0 then
VarArrayCopyForEach(Dest, Source, VarCopyCopyProc)
// otherwise try for custom
else if FindCustomVariantType(Source.VType, LSourceHandler) then
LSourceHandler.Copy(Dest, Source, False)
// finally let the OS deal with it
else
VarResultCheck(VariantCopy(Dest, Source));
end;
procedure _VarCopy(var Dest: TVarData; const Source: TVarData);
begin
// if they are the same then don't do anything
if @Dest = @Source then
Exit;
// inline data or a byref
if (Source.VType and varDeepData) = 0 then
begin
// not inline dest of a byref
if (Dest.VType and varDeepData) <> 0 then
VarClearDeep(Dest);
// copy the data
Dest.RawData[0] := Source.RawData[0];
Dest.RawData[1] := Source.RawData[1];
Dest.RawData[2] := Source.RawData[2];
Dest.RawData[3] := Source.RawData[3];
end
else
VarCopyDeep(Dest, Source);
end;
procedure VarClearDeep(var V: TVarData);
var
LHandler: TCustomVariantType;
begin
// quick test for the simple ones
if (V.VType < varInt64) then
VarResultCheck(VariantClear(V))
// clear the pascal string correctly for reference counting
else if V.VType = varString then
begin
V.VType := varEmpty;
String(V.VString) := '';
end
// let CORBA deal with its own type
else if V.VType = varAny then
ClearAnyProc(V)
// custom handle the arrays
else if (V.VType and varArray) <> 0 then
VarArrayClear(V)
// ok, finally is it a custom variant type?
else if FindCustomVariantType(V.VType, LHandler) then
LHandler.Clear(V)
// finally let the OS attempt to deal with it
else
VarResultCheck(VariantClear(V));
end;
procedure _VarClear(var V: TVarData);
begin
// byrefs and those inline data types are easy
if (V.VType and varDeepData) = 0 then
V.VType := varEmpty
else
VarClearDeep(V);
end;
DiamondShark (2006-08-17 16:30:00) [6]Дайте две...
=-0
Сергей М. (2006-08-17 16:27:00) [7]а на, держи:
procedure _VarCopy(var Dest: TVarData; const Src: TVarData);
begin
if Assigned(VarCopyProc) then
VarCopyProc(Dest, Src)
else
Error(reVarInvalidOp);
end;
DiamondShark (2006-08-17 16:26:00) [8]Дайте текст System._VarCopy из седьмой.
Сергей М. (2006-08-17 16:25:00) [9]
> GrBob (17.08.06 16:15) [23]
Гонишь ты)..
Гонишь от начала и до конца.
Invalid Variant Type - это ошибка времени компиляции, а не времени исполнения.
А компилятоору фиолетово, в какой опер.среде он запущен - он либо работает как положено либо не работает в принципе.
DiamondShark (2006-08-17 16:24:00) [10]Похоже, тип действительно не поддерживается API :(
var
A, B: OleVariant;
Z: TVariantArg absolute A;
begin
A := 1.234; //Это будет VT_CY
Z.vt := 20; //VT_I8, в Дельфи5 не описана
OleCheck( VariantClear(A) ); // Exception "Bad variant type"
end;
А в пятой дельфе в System._VarCopy вызов VariantClear происходит только для типов, требующих финализации, после разных проверок ;)
Если в седьмой решили "упростить", и просто тупо вызывают VariantClear, то будет исключение ;)
GrBob (2006-08-17 16:15:00) [11]
> Ой, как интересно. А версия Дельфи какая?
Delphi 7
GrBob (2006-08-17 16:14:00) [12]
> И давай уже не будем дуракека валять)
> Если ничерта не понимаешь в ASM, предложенный тебе отладчиком
> при пошаговой трассировке, то так честно и признайся)
Ууууу.... так вот ты про какой отладчик говоришь. Тогда да, с Асмом я знаком только на уровне университетского курса, и то что там пишут мне не осилить.
> Если интересно можешь почитать Дж.Рихтера Windows для профессионалов
> там эти проблемы подымаются.
Да, я предполагаю нечто подобное, Рихтера я читал, хоть и не всего, но с проблемой в принципе знаком. Мне не хватает конкретики, как это коснулось вариантного типа. Есть ли это в Рихтере (может в той части, которую я не прочел :))?
DiamondShark (2006-08-17 16:13:00) [13]Ой, как интересно. А версия Дельфи какая?
Пятая дельфи вообще отказывается компилировать
A := Int64(123);
Говорит: "Incompatible types Variant and Int64"
Пришлось так:
var
A, B: Variant;
Z: TVariantArg absolute A;
begin
A := 1.234; //Это будет VT_CY
Z.vt := 20; //VT_I8, в Дельфи5 не описана
B := True;
A := B;
end;
Ошибок нет.
Win2000Prof
DelphiLexx (2006-08-17 16:03:00) [14]
> Нет, не возникает. Проблема именно в int64.
Так я и думал. Это особенности OS - архитектура 2003 винды сильно стала отличаться от архитектуры 2000. Многие Api-функции были переписаны под работу c форматом Int64 т.е. встраивается некое подобие 64 - разрядной среды, чего в Win2000 нет - отсюда и все проблемы. Если интересно можешь почитать Дж.Рихтера Windows для профессионалов там эти проблемы подымаются.
Сергей М. (2006-08-17 15:46:00) [15]
> дуракека
О це я загнул))
Сергей М. (2006-08-17 15:46:00) [16]
> GrBob (17.08.06 14:27)
И давай уже не будем дуракека валять)
Если ничерта не понимаешь в ASM, предложенный тебе отладчиком при пошаговой трассировке, то так честно и признайся)
Сергей М. (2006-08-17 15:43:00) [17]
> GrBob (17.08.06 15:39) [15]
> Интересно, а как я иначе локализовал проблему?
Для локализации проблемы сие не надо.
Сие надо для ВЫЯСНЕНИЯ причин проблемы.
Ну а если для тебя встроенный отладчик - ненужная фитюлька в составе среды, то я умываю руки)
clickmaker (2006-08-17 15:42:00) [18]
> Нет, не возникает. Проблема именно в int64
ну хорошо, а если не приводить, а константу подсунуть?
A := $000000000000000A;
GrBob (2006-08-17 15:39:00) [19]
> Ставишь среду на проблемную машину, торассируешь пошагово
> проблемный код - получаешь ответ на вопрос.
Интересно, а как я иначе локализовал проблему? Повторяю еще раз: падение происходит на строчке A := B. Вопрос: почему?
> Скажи, пожалуйста в таком случае возникает ошибка?
Нет, не возникает. Проблема именно в int64.
DelphiLexx (2006-08-17 15:36:00) [20]
> Но вопрос остался - почему такое может происходить?
> Где может быть описана работа Варианта и инт64?
Скажи, пожалуйста в таком случае возникает ошибка?
procedure Proc;
var
A, B: Variant;
begin
A := 10; //не приводим к Int64
B := True;
A := B;
end;