2016-10-21 21 views
3

Я существующий интерфейс API, который имеет OUT, RetVal параметр, как показано нижеКак объявить IN, опциональный параметр вместе с OUT, RetVal параметром в IDL

HRESULT Test([out, retval] VARIANT_BOOL *pVal); 

меня попросили, чтобы добавить дополнительный IN параметр , поэтому я попытался ниже, поскольку параметр RetVal по правилу должен быть последним параметром я был вынужден ставить дополнительный IN параметра в качестве первого параметра

HRESULT Test([in, optional, defaultvalue(VARIANT_FALSE)] VARIANT_BOOL optFlag, [out, retval] VARIANT_BOOL *pVal); 

Когда я попытался вызвать этот API, как показано ниже, с только обязательный OU T параметров от C++ ошибки компилятора компонент, говоря, два параметра необходимы для этого вызова

VARIANT_BOOL outFlag; 
pInterface->Test(&outFlag); 

Пожалуйста, дайте мне знать, что мне не хватает здесь, чтобы достичь этой комбинации.

+0

Атрибут [optional] полезен, когда компилятор использует библиотеку типов для импорта объявлений. Они обычно также переписывают функцию, поэтому [retval] становится возвращаемым значением, а код ошибки HRESULT превращается в исключение. Вы не используете эту функцию, похоже, что вы используете сгенерированный файл .h. И игнорировать HRESULT, плохую идею. Рассмотрим директиву #import. –

ответ

1

Связи C++, сгенерированные компилятором IDL microsoft, не поддерживают функцию необязательного и/или значения по умолчанию.

Попробуйте с C# или аналогичного.

2

MSDN on optional IDL attribute:

[Факультативный] атрибут действителен только если параметр имеет тип VARIANT или Varianta *.

Вы пытаетесь применить его к VARIANT_BOOL.

Существует также намек там на порядок параметров с такими атрибутами:

Компилятор MIDL принимает следующий порядок параметров (слева направо):

  • Требуемые параметры (параметры, которые не имеют атрибутов [defaultvalue] или [optional]),
  • Дополнительные параметры с атрибутом [defaultvalue],
  • Параметры с опцией [optio NAL] атрибут и без атрибута [DefaultValue],
  • [LCID] параметр, если таковые имеются,
  • [RetVal] Параметр

IDL компилятор выдает предупреждение при компиляции такой метод:

Предупреждение MIDL2401: [defaultvalue] применяется к не-VARIANT и [необязательно]. Пожалуйста, удалите [опционально]: [Параметр «optFlag» процедуры «Тест» ...

Тем не менее атрибуты скомпилированы в библиотеку типов и доступны для импортеров. Например, C# импортирует метод как:

bool Test(bool optFlag = false); 

который должен соответствовать вашим ожиданиям. Однако это скорее бесплатный бонус, так как импортеры библиотеки типов могут свободно интерпретировать флаги (особенно.превышая документированные ограничения) по своему усмотрению. C++ #import не генерирует метод с необязательным параметром.

+0

Это на самом деле не так. Посмотрите на wincodec.idl, например, обратите внимание на необязательный ULONG. Afaik полностью зависит от компилятора, чтобы интерпретировать его так, как он хочет. –

+0

@HansPassant: такой необязательный атрибут отражается как некоторый флаг в библиотеке типов, потому что импорт видит его обратно. Импортеры могут свободно интерпретировать это так, как они этого хотят, правильно, но им не нужно выходить за рамки документированного утверждения, ограничивающего только варианты. Кроме того, в этом конкретном сценарии, о котором идет речь, есть предупреждение компилятора IDL, объясняющее проблему: «warning MIDL2401: [defaultvalue] применяется к не-VARIANT и [необязательно]. Удалите [optional] ...» –

+0

Это в основном это относится к языкам более высокого уровня (Automation/IDispatch) (VB/VBA/VBScript, .NET), где есть понятие «Отсутствующее» значение VARIANT (технически представленное VT_ERROR/DISP_E_PARAMNOTFOUND) https://support.microsoft. ком/EN-US/кб/154039 –