Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Variant и Int64


Страницы:   1 2

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;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо