gpt4 book ai didi

c++ - IDL 文件和 C++ 头文件中的 defaultvalue 和 retval 参数排序

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:39:15 25 4
gpt4 key购买 nike

我正在尝试更新现有的 COM API 以包含新的可选输出参数,但遇到了 IDL 文件和关联的 C++ 头文件中参数类型强制排序的问题。

以前我有一个像这样的 IDL 文件(为了保护无辜者更改了名称):

HRESULT CreateSomething(
[in] BSTR base_uri,
[in] ISomethingDescription* something_description,
[out, retval] BSTR* something_uri
);

相关的 C++ header 如下所示:

HRESULT __stdcall CreateSomething(
/* [in] */ BSTR study_uri,
/* [in] */ ISomethingDescription* something_description,
/* [out, retval] */ BSTR* something_uri
);

这需要更新以添加一个可选的输出参数,该参数可以为一些客户提供额外的错误报告信息,遵循针对内部 SDK 其余部分的现有模式。

为此,我计划将 IDL 文件更新为如下所示:

HRESULT CreateSomething(
[in] BSTR base_uri,
[in] ISomethingDescription* something_description,
[out, defaultvalue(0)] ErrorCode* error_code,
[out, retval] BSTR* something_uri
);

其中 ErrorCode 是在单独的 IDL 文件中定义的枚举。这遵循我在网上看到的关于如何对具有 defaultvalue 和 retval 属性的参数进行排序的指南。但是,当我尝试更新 C++ 头文件时,我遇到了默认参数不在参数列表末尾的问题,即

HRESULT __stdcall CreateSomething(
/* [in] */ BSTR study_uri,
/* [in] */ ISomethingDescription* something_description,
/* [out, defaultvalue(0)] */ ErrorCode* error_code = 0, // this is clearly wrong
/* [out, retval] */ BSTR* something_uri
);

我在 MSDN 上看到的文档似乎表明您可以在同一函数定义中使用具有 defaultvalue 和 retval 属性的参数,并且我看到了一些包含此类定义的 IDL 文件示例,但我无法弄清楚它是如何实现的可以编写等效的 C++ 定义。

一些客户端(和我们自己的测试代码)直接使用 MIDL 生成的头文件,所以如果我从原始 C++ 头文件中省略默认值,MIDL 生成文件中的生成函数不包含默认值条目,即它看起来像这样:

virtual HRESULT STDMETHODCALLTYPE CreateSomething( 
/* [in] */ BSTR base_uri,
/* [in] */ ISomethingDescription *something_description,
/* [defaultvalue][out] */ ErrorCode *error_code,
/* [retval][out] */ BSTR *something_uri) = 0;

我们 SDK 中的类似功能包括 IDL 文件和 C++ header 中的默认值 - 并不是说​​整个方法没有问题。

如有任何帮助/建议,我们将不胜感激。

最佳答案

MSDN is pretty clear about the parameters :

The MIDL compiler accepts the following parameter ordering (from left-to-right):

  1. Required parameters (parameters that do not have the [defaultvalue] or [optional] attributes),
  2. optional parameters with or without the [defaultvalue] attribute,
  3. parameters with the [optional] attribute and without the [defaultvalue] attribute,
  4. [lcid] parameter, if any,
  5. [retval] parameter

请注意,没有提及“非可选默认值”参数。这是因为默认值仅适用于可选 - 这是有道理的,因为不是可选的参数始终具有显式值,没有适用的默认值。

所以你的默认值参数必须是可选的,然后新的约束适用:"The [optional] attribute is valid only if the parameter is of type VARIANT or VARIANT *." ,这意味着您的可选枚举参数基本上无效。 MIDL 编译器可能会接受这一点并将相应的标志放在类型库上,但最终这并不是预期的工作方式:默认值仅适用于变体。

然后当您从 IDL 生成 C++ header 时,您会发现可选参数只是一个标记。脚本语言等开发环境可能会检测到它,以便分别更新此 COM 方法的语法,但在 C++ 端,参数始终存在并且基本上是强制性的。您基本上唯一拥有的是特殊约定,可以看到调用者没有没有默认值的可选参数的值,在这种情况下,您在各自的变体参数。

关于c++ - IDL 文件和 C++ 头文件中的 defaultvalue 和 retval 参数排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26182072/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com