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

В процедуре работаю с 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
29.05.2018, 12:43
    #39651706
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
Кроик СемёнЕсть идеи, что бы проверить/настроить/подкрутить?
Разные ком-объекты (версии)?
...
Рейтинг: 0 / 0
29.05.2018, 12:48
    #39651710
Кроик Семён
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
wadmanРазные ком-объекты (версии)?
Ком-объекты одной версии.
Если скомпилирую на том компьютере и принесу EXE-шник на мой, то тоже нормально отрабатывает.
...
Рейтинг: 0 / 0
29.05.2018, 13:08
    #39651726
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
$16 = vt_int и специальной очистки не требует.

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


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


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

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

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

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

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

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


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

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

в Delphi 6 + Update Pack 1 есть
в Delphi 6 + Update Pack 2 (у меня) снова нет
...
Рейтинг: 0 / 0
29.05.2018, 13:58
    #39651781
Квейд
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
Код: 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
29.05.2018, 14:00
    #39651782
Квейд
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
VarClearRare это из Delphi 5

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

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

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

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

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

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

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

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

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

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

VarIsArray
VarArrayDimCount
VarArrayLowBound
VarArrayHighBound
vArr[index,index]
...
Рейтинг: 0 / 0
29.05.2018, 17:26
    #39651961
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек
_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
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как победить "Invalid variant operation" при обнулении переменной, полученной из COM-объек / 25 сообщений из 27, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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