Текущий архив: 2006.10.08;
Скачать: CL | DM;
ВнизVariant и Int64 Найти похожие ветки
← →
GrBob (2006-08-17 14:27) [0]Есть такой код:
procedure Proc;
var
A, B: Variant;
begin
A := Int64(10);
B := True;
A := B;
end;
В Win 2003 Server все работает как надо, а вот в 2000 падает с ошибкой "Invalid Variant Type". Кто-нибудь знает почему?
← →
Ketmar © (2006-08-17 14:34) [1]потому что invalid variant type? %-)
← →
GrBob (2006-08-17 14:42) [2]
> потому что invalid variant type?
Ответ не исчерпывает вопрос полностью. Почему же в 2003 тогда не падает, а?
← →
clickmaker © (2006-08-17 14:49) [3]бессмысленный код какой-то...
← →
Сергей М. © (2006-08-17 14:54) [4]К тому же при детальном разбирательстве выяснится что автор попросту врет)
← →
GrBob (2006-08-17 14:56) [5]
> бессмысленный код какой-то...
Если я вам напишу несколько тысяч строк кода, вам станет понятнее? Я просто уже локализовал проблему, сведя ее вот к такому маленькому фрагменту. В МСДН я ничего особенного не нашел про приведение boolean к int64 в variant или чего-нибудь подобного.
← →
Ketmar © (2006-08-17 14:58) [6]наверное, ввели в вариант поддержку int64? а вообще -- всё это умозрительно, не видел я 2003.
мастера, поправьте, если что...
тут всё завязано на OleVariant"ы. в 2003, видимо, есть что-то для работы с int64, а вот в 2k ещё не было.
← →
GrBob (2006-08-17 14:58) [7]
> К тому же при детальном разбирательстве выяснится что автор
> попросту врет)
???
← →
GrBob (2006-08-17 15:00) [8]
> наверное, ввели в вариант поддержку int64?
Я тоже склоняюсь к этому, но почему же тогда МСДН молчит, и Сергей М. обвиняет во лжи? Может дело не в виндах вобще?
← →
clickmaker © (2006-08-17 15:10) [9]
> [8] GrBob (17.08.06 15:00)
а если A := VarAsType(B, varInt64)?
← →
GrBob (2006-08-17 15:17) [10]
> а если A := VarAsType(B, varInt64)?
Так не падает. Но, к сожалению, такой подход мне не очень подходит, т.к. не всегда (в своей программе, а не в примере) сюда приходит Int64, может придти и строка, и в этом случае приводить к Int64 как то не с руки :) Во-вторых нужно после этого приводить обратно к Boolean и получим что-то страшное типаif VarIsType(A, varInt64) then
A := VarAsType(VarAsType(B, varInt64), varBoolean)
else
A := B;
чего хотелось бы избежать.
← →
clickmaker © (2006-08-17 15:22) [11]
> сюда приходит Int64, может придти и строка
сдается мне, что в этом месте логика работы прихрамывает.. Не очень все прозрачно и однозначно, поэтому и грабли.
В конце концов
A := VarAsType(B, VarType(A));
← →
GrBob (2006-08-17 15:28) [12]Спасибо, проблему решил другим способом, теперь такого присваивания просто нет :). Но вопрос остался - почему такое может происходить? Где может быть описана работа Варианта и инт64?
← →
Сергей М. © (2006-08-17 15:32) [13]
> вопрос остался - почему такое может происходить?
Вопрос не программиста, но ньюби.
Ставишь среду на проблемную машину, торассируешь пошагово проблемный код - получаешь ответ на вопрос.
← →
DelphiLexx © (2006-08-17 15:36) [14]
> Но вопрос остался - почему такое может происходить?
> Где может быть описана работа Варианта и инт64?
Скажи, пожалуйста в таком случае возникает ошибка?
procedure Proc;
var
A, B: Variant;
begin
A := 10; //не приводим к Int64
B := True;
A := B;
end;
← →
GrBob (2006-08-17 15:39) [15]
> Ставишь среду на проблемную машину, торассируешь пошагово
> проблемный код - получаешь ответ на вопрос.
Интересно, а как я иначе локализовал проблему? Повторяю еще раз: падение происходит на строчке A := B. Вопрос: почему?
> Скажи, пожалуйста в таком случае возникает ошибка?
Нет, не возникает. Проблема именно в int64.
← →
clickmaker © (2006-08-17 15:42) [16]
> Нет, не возникает. Проблема именно в int64
ну хорошо, а если не приводить, а константу подсунуть?
A := $000000000000000A;
← →
Сергей М. © (2006-08-17 15:43) [17]
> GrBob (17.08.06 15:39) [15]
> Интересно, а как я иначе локализовал проблему?
Для локализации проблемы сие не надо.
Сие надо для ВЫЯСНЕНИЯ причин проблемы.
Ну а если для тебя встроенный отладчик - ненужная фитюлька в составе среды, то я умываю руки)
← →
Сергей М. © (2006-08-17 15:46) [18]
> GrBob (17.08.06 14:27)
И давай уже не будем дуракека валять)
Если ничерта не понимаешь в ASM, предложенный тебе отладчиком при пошаговой трассировке, то так честно и признайся)
← →
Сергей М. © (2006-08-17 15:46) [19]
> дуракека
О це я загнул))
← →
DelphiLexx © (2006-08-17 16:03) [20]
> Нет, не возникает. Проблема именно в int64.
Так я и думал. Это особенности OS - архитектура 2003 винды сильно стала отличаться от архитектуры 2000. Многие Api-функции были переписаны под работу c форматом Int64 т.е. встраивается некое подобие 64 - разрядной среды, чего в Win2000 нет - отсюда и все проблемы. Если интересно можешь почитать Дж.Рихтера Windows для профессионалов там эти проблемы подымаются.
← →
DiamondShark © (2006-08-17 16:13) [21]Ой, как интересно. А версия Дельфи какая?
Пятая дельфи вообще отказывается компилировать
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
← →
GrBob (2006-08-17 16:14) [22]
> И давай уже не будем дуракека валять)
> Если ничерта не понимаешь в ASM, предложенный тебе отладчиком
> при пошаговой трассировке, то так честно и признайся)
Ууууу.... так вот ты про какой отладчик говоришь. Тогда да, с Асмом я знаком только на уровне университетского курса, и то что там пишут мне не осилить.
> Если интересно можешь почитать Дж.Рихтера Windows для профессионалов
> там эти проблемы подымаются.
Да, я предполагаю нечто подобное, Рихтера я читал, хоть и не всего, но с проблемой в принципе знаком. Мне не хватает конкретики, как это коснулось вариантного типа. Есть ли это в Рихтере (может в той части, которую я не прочел :))?
← →
GrBob (2006-08-17 16:15) [23]
> Ой, как интересно. А версия Дельфи какая?
Delphi 7
← →
DiamondShark © (2006-08-17 16:24) [24]Похоже, тип действительно не поддерживается 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, то будет исключение ;)
← →
Сергей М. © (2006-08-17 16:25) [25]
> GrBob (17.08.06 16:15) [23]
Гонишь ты)..
Гонишь от начала и до конца.
Invalid Variant Type - это ошибка времени компиляции, а не времени исполнения.
А компилятоору фиолетово, в какой опер.среде он запущен - он либо работает как положено либо не работает в принципе.
← →
DiamondShark © (2006-08-17 16:26) [26]Дайте текст System._VarCopy из седьмой.
← →
Сергей М. © (2006-08-17 16:27) [27]а на, держи:
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:30) [28]Дайте две...
=-0
← →
clickmaker © (2006-08-17 16:33) [29]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:40) [30]Ага.
Для VT_I8 мы попадём сюда:
// finally let the OS attempt to deal with it
else
VarResultCheck(VariantClear(V));
;-)
Всё понятно.
← →
Ketmar © (2006-08-17 16:58) [31]> [30] DiamondShark © (17.08.06 16:40)
как я сразу и предполагал. ай да я, ай да умник! %-)
← →
Anatoly Podgoretsky © (2006-08-17 19:05) [32]DiamondShark © (17.08.06 16:30) [28]
И побольше
← →
GrBob (2006-08-24 16:16) [33]Снова всем привет. Теперь возник такой вопрос: А можно ли вобще иметь вариантный массив 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;
Падает на присваивании :(
Страницы: 1 вся ветка
Текущий архив: 2006.10.08;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.039 c