Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.55 MB
Время: 0.052 c
1-1156420595
DevilDevil
2006-08-24 15:56
2006.10.08
OnKeyDown работает некорректно


15-1158505411
Tirael
2006-09-17 19:03
2006.10.08
чайник


2-1158928058
Crazy monkey
2006-09-22 16:27
2006.10.08
Как сократить запись?


2-1158987058
Juju
2006-09-23 08:50
2006.10.08
Excel создал, а как убить?


2-1158766989
Image
2006-09-20 19:43
2006.10.08
Кто нибудь знает как сохранить форму вместе со всем содержимым в