powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
25 сообщений из 27, страница 1 из 2
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651705
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!

В процедуре работаю с COM-объктом, который возвращает мне OLEVariant-переменную (VarArray, но это не важно).
Процедура отрабатывает полностью, до последней строчки. А далее вылетает исключение "Invalid variant operation"

Код: pascal
1.
2.
3.
4.
5.
6.
7.
procedure TMyForm.Button1Click(Sender: TObject);
var
   vArr : OLEVariant;
begin
   FCOMObject.CallSomeProcedure(vArr);
   ...
end;



и дебаггер останавливается здесь:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
//unit Variants

procedure VarClearRare(var V: TVarData);
var
  LHandler: TCustomVariantType;
begin

  // let CORBA deal with its own type
  if V.VType = varAny then
    ClearAnyProc(V)

  // ok, finally is it a custom variant type?
  else if FindCustomVariantType(V.VType, LHandler) then
    LHandler.Clear(V)
  else
    VarInvalidOp;
end;



вот содержимое переменной "V"
Код: pascal
1.
2.
V.VType: 22, 
V.VBytes: (0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 248, 51, 30, 0)



причем такой константы для VType = 22 ($0016) нет

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
{ Variant type codes (wtypes.h) }

  varEmpty    = $0000; { vt_empty       }
  varNull     = $0001; { vt_null        }
  varSmallint = $0002; { vt_i2          }
  varInteger  = $0003; { vt_i4          }
  varSingle   = $0004; { vt_r4          }
  varDouble   = $0005; { vt_r8          }
  varCurrency = $0006; { vt_cy          }
  varDate     = $0007; { vt_date        }
  varOleStr   = $0008; { vt_bstr        }
  varDispatch = $0009; { vt_dispatch    }
  varError    = $000A; { vt_error       }
  varBoolean  = $000B; { vt_bool        }
  varVariant  = $000C; { vt_variant     }
  varUnknown  = $000D; { vt_unknown     }
//varDecimal  = $000E; { vt_decimal     } {UNSUPPORTED}
                       { undefined  $0f } {UNSUPPORTED}
  varShortInt = $0010; { vt_i1          }
  varByte     = $0011; { vt_ui1         }
  varWord     = $0012; { vt_ui2         }
  varLongWord = $0013; { vt_ui4         }
  varInt64    = $0014; { vt_i8          }
//varWord64   = $0015; { vt_ui8         } {UNSUPPORTED}

  { if adding new items, update Variants' varLast, BaseTypeMap and OpTypeMap }
  varStrArg   = $0048; { vt_clsid    }
  varString   = $0100; { Pascal string; not OLE compatible }
  varAny      = $0101; { Corba any }
  varTypeMask = $0FFF;
  varArray    = $2000;
  varByRef    = $4000;




Решил попробовать принудительно выставить переменную в Unassigned.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TMyForm.Button1Click(Sender: TObject);
var
   vArr : OLEVariant;
begin
   FCOMObject.CallSomeProcedure(vArr);
   ...
   vArr := Unassigned;
end;



Не помогает.
Но самое интересное, если скомпилировать на другом компьютере, то помогло (везде Delphi 6, правда там Update Pack 1, а у меня Update Pack 2),

Хелп! Есть идеи, что бы проверить/настроить/подкрутить?
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651706
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик СемёнЕсть идеи, что бы проверить/настроить/подкрутить?
Разные ком-объекты (версии)?
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651710
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanРазные ком-объекты (версии)?
Ком-объекты одной версии.
Если скомпилирую на том компьютере и принесу EXE-шник на мой, то тоже нормально отрабатывает.
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651726
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
$16 = vt_int и специальной очистки не требует.

Посмотри что там вызывается до VarClearRare.
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651735
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сделал хак чтобы проверить предположение, что Delphi не может определить вариант-тип. Мало ли куда там дебаггер указывает, может неправильно :)
Код: pascal
1.
2.
   //вместо vArr := Unassigned;
   TVarData(vArr).VType := varNull;


Exception пропал, идем дальше.


GunSmoker,
спасибо, сейчас посмотрю
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651751
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще странная вешь: разные Variants.pas в Delphi моем и на том компьютере, у меня нет VarClearRare :)
Я точку останова дебаггера показывал с того компьютера, у меня она не определяется.
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651756
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Перенес Variants.pas с того компьютера на свой и положил в папку с проектом и всё отработало без Exception'a.

Что теперь посоветуете?
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651757
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик Семён> Процедура отрабатывает полностью, до последней строчки.

А если переменная не локальная, а глобальная ?
И что происходит, если вручную вызвать VarClear?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651759
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик Семён> Что теперь посоветуете?

Не скакать по версиям :)

P.S. Еще в старых версиях варианты менялись почти в каждой версии -
то функция из одного модуля в другой переедет, то ещё что. :-)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651762
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чьи-то шаловливые ручки покопались в Delphi? Потому что VarClearRare в сырцах Delphi 6 вообще нет (я проверил).
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651768
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамА если переменная не локальная, а глобальная ?

"Invalid variant operation" вылетает тогда при завершении программы


Гаджимурадов РустамИ что происходит, если вручную вызвать VarClear?

вылетает то же самое исключение
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651774
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmokerЧьи-то шаловливые ручки покопались в Delphi? Потому что VarClearRare в сырцах Delphi 6 вообще нет (я проверил).

в Delphi 6 + Update Pack 1 есть
в Delphi 6 + Update Pack 2 (у меня) снова нет
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651781
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
procedure VarClearRare(var V: TVarData);
var
  LHandler: TCustomVariantType;
begin

  // let CORBA deal with its own type
  if V.VType = varAny then
    ClearAnyProc(V)

  // ok, finally is it a custom variant type?
  else if FindCustomVariantType(V.VType, LHandler) then
    LHandler.Clear(V)
  else
    VarInvalidOp;
end;



Очень похожа на VarClearDeep из Variants.pas
комментарии совпадают побуквенно


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
procedure VarClearDeep(var V: TVarData);
var
  LHandler: TCustomVariantType;
begin
  // quick test for the simple ones
  if (V.VType < varInt64) then
    VarResultCheck(VariantClear(V))

  else if V.VType = varString then
  begin
{$IFNDEF NEXTGEN}
    V.VType := varEmpty;
    AnsiString(V.VString) := '';
{$ELSE NEXTGEN}
    VarInvalidOp;
{$ENDIF !NEXTGEN}
  end

  // clear the pascal unicode string correctly for reference counting
  else if V.VType = varUString then
  begin
    V.VType := varEmpty;
    UnicodeString(V.VUString) := '';
  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
  begin
    LHandler.Clear(V);
    V.VPointer := nil;
  end

  // finally let the OS attempt to deal with it
  else
  begin
    // sometimes the OS will return an error that it doesn't know what to do
    // with the given VType.  We don't know what to do either, so we'll just
    // punt here and ignore any errors and then VarInit the variant.
    VariantClear(V);
    VariantInit(V);
  end;
end;
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651782
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VarClearRare это из Delphi 5

http://www.delphigroups.info/2/cc/260772.html
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651787
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нету такого в Delphi 5. И это я тоже посмотрел.
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651791
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ключевое отличие:
авторfinally let the OS attempt to deal with it
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651802
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик Семён> в Delphi 6 + Update Pack 1 есть
> в Delphi 6 + Update Pack 2 (у меня) снова нет

Мне казалось, у тебя свежак, ХЕстопицот.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651804
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
P.S. В семёрке нет, хотя VarClearDeep содержит часть кода, да.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651809
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопросы

Чем потенциально могут грозить эти два грязных варианта?

1) если оставить этот хак?
//вместо vArr := Unassigned;
TVarData(vArr).VType := varNull;

2) Если подменить Variants.pas на другую версию, и только для этого проекта
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651815
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик СемёнЧем потенциально могут грозить эти два грязных варианта?

1) если оставить этот хак?
//вместо vArr := Unassigned;
TVarData(vArr).VType := varNullутечкой если внутри есть чему утечь
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651884
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так работает?
Код: pascal
1.
2.
3.
4.
5.
6.
procedure TMyForm.Button1Click(Sender: TObject);
var
   vArr : OLEVariant;
begin
   FCOMObject.CallSomeProcedure(vArr);
end;

Если да, то ищи где ты в
Кроик Семён
Код: pascal
1.
...

портишь память
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651928
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

к сожалению, так тоже ошибка.
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651933
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик Семёнк сожалению, так тоже ошибка.Если возвращаетсяКроик Семён
Код: pascal
1.
V.VType: 22,

То ты никак не обработаешь это значение. Это неизвестный тип и неизвестно ни как с ним работать, ни как прочитать значение, ни как очистить. Это натуральный мусор
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651958
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
но массив это тоже :)
Все функции работы с массивами отлично работают

VarIsArray
VarArrayDimCount
VarArrayLowBound
VarArrayHighBound
vArr[index,index]
...
Рейтинг: 0 / 0
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
    #39651961
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_То ты никак не обработаешь это значение. Это неизвестный тип и неизвестно ни как с ним работать, ни как прочитать значение, ни как очистить. Это натуральный мусор

И именно поэтому:
Код: pascal
1.
2.
3.
4.
5.
6.
// finally let the OS attempt to deal with it
  else
  begin
    VariantClear(V);
    VariantInit(V);
  end;



Остаётся вопрос, что за код у ТС (VarClearRare), и почему он не отправляет освобождение ОС. Возможно, это баг в Delphi 6, который был исправлен.
...
Рейтинг: 0 / 0
25 сообщений из 27, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]