Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.10.08;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.54 MB
Время: 0.041 c
2-1158730599
svt
2006-09-20 09:36
2006.10.08
Уважаемые мастера, подскажите как правильно выполнить


2-1158529125
Aleksandr
2006-09-18 01:38
2006.10.08
net и чаты


1-1156336513
yel
2006-08-23 16:35
2006.10.08
DevExpress : ExpressFlowChart Suite


2-1158729756
o_serg
2006-09-20 09:22
2006.10.08
Не загружается Delphi 2005


15-1158514450
ArtemESC
2006-09-17 21:34
2006.10.08
Запутался с дискетами...





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский