IAutomation — как получить значение аргумента, переданного по указателю?

#c #com #automation

#c #com #автоматизация

Вопрос:

IAutomation — как получить значение аргумента, переданного по указателю?

В .idl-файл записан:

 interface IAutomation : IDispatch {
        [id(0x000000e0), helpstring("Returns if the player is ready. Many of the other commands fail as long as the player is not ready.")]
        HRESULT GetReady([out] VARIANT* Ready);
};
  

Я полагаю, GetReady() — метод, а не свойство.

Если я пытаюсь использовать библиотеку VOLE:

 object player = object::create("StereoPlayer.Automation", CLSCTX_LOCAL_SERVER, vole::coercion_level::valueCoercion);
VARIANT var;
::VariantInit(amp;var);
VARIANT pos = player.invoke_method(vole::of_type<VARIANT>(), L"GetReady", var);
  

Но получить ошибку компоновщика:

 error LNK2019: unresolved external symbol "public: static struct tagVARIANT __cdecl vole::com_return_traits<struct tagVARIANT>::convert(struct tagVARIANT const amp;,enum vole::coercion_level::coercion_level)" (?convert@?$com_return_traits@UtagVARIANT@@@vole@@SA?AUtagVARIANT@@ABU3@W4coercion_level@42@@Z) referenced in function "public: struct tagVARIANT __thiscall vole::object::invoke_method<struct tagVARIANT,struct tagVARIANT>(struct vole::of_type<struct tagVARIANT>,unsigned short const *,struct tagVARIANT const amp;)" (??$invoke_method@UtagVARIANT@@U1@@object@vole@@QAE?AUtagVARIANT@@U?$of_type@UtagVARIANT@@@1@PBGABU2@@Z)
  

Вызов других методов, которые ничего не возвращают, работает отлично.

Также я пытаюсь напрямую вызвать метод IDispatch::Invoke(), как описано в разделе «Как использовать Visual C для доступа к свойствам DocumentProperties с автоматизацией» . Но неправильно понял, как возвращаемое значение тоже.

Ответ №1:

Я не знаком с VOLE, но если я правильно читаю его исходный код, вам нужно сделать это вместо этого:

 VARIANT pos = player.invoke_method<VARIANT>(L"GetReady"); 
  

Или это:

 VARIANT pos = player.invoke_method(vole::of_type<VARIANT>(), L"GetReady"); 
  

Вы пытаетесь передать a в VARIANT качестве [in] параметра в GetReady() , но у него нет такого параметра. Вместо этого у [out] него есть параметр, который представлен возвращаемым значением invoke_method() , поэтому вам не нужно передавать свой собственный VARIANT параметр.

invoke_method() выполняет VARIANT внутренние преобразования по типу, поэтому, предполагая GetReady() , что на самом деле возвращается логическое значение, заключенное в a VARIANT , вы даже можете сделать что-то вроде этого:

 VARIANT_BOOL ready = player.invoke_method<VARIANT_BOOL>(L"GetReady"); 
  

Или даже:

 bool ready = player.invoke_method<bool>(L"GetReady"); 
  

Комментарии:

1. Если вызвать invoke_method без параметра — invoke() возвращает hr=0x8002000e Недопустимое количество параметров.