IDL文件和C++头文件中的defaultvalue和retval参数排序
defaultvalue and retval parameter ordering in IDL file and C++ header file
我正在尝试更新现有的COM API以包含新的可选输出参数,并且遇到了在IDL文件和关联的C++头文件中强制排序参数类型的问题。
以前我有一个像这样的IDL文件(为了保护无辜者而更改了名称):
HRESULT CreateSomething(
[in] BSTR base_uri,
[in] ISomethingDescription* something_description,
[out, retval] BSTR* something_uri
);
相关的C++头看起来像:
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++头中的默认值,这并不是说整个方法没有问题。
如有任何帮助/建议,我们将不胜感激。
MIDL编译器接受以下参数顺序(从左到右):
- 必需参数(不具有[defaultvalue]或[optional]属性的参数)
- 带有或不带有[defaultvalue]属性的可选参数
- 具有[可选]属性但不具有[默认值]属性的参数
- [lcid]参数(如果有的话)
- [retval]参数
注意,没有提到";不是可选的默认值";参数这是因为默认值仅适用于可选参数-这是有意义的,因为非可选参数总是具有显式值,而不适用默认值。
因此,您的默认值参数必须是可选的,然后新的约束才适用:;只有当参数的类型为VARIANT或VARIANT*时,[可选]属性才有效&";,这意味着您的可选枚举参数基本无效。MIDL编译器可能会接受这一点,并将相应的标志放在类型库上,但最终这并不是它最初的工作方式:默认值只适用于变体。
然后,当您从IDL生成C++头时,您会发现可选参数只是一个标记。脚本语言等开发环境可能会检测到它,以便分别更新该COM方法的语法,但在C++方面,该参数始终存在,并且基本上是强制性的。您基本上唯一拥有的是一种特殊的约定,即调用者没有可选参数的值而没有默认值,在这种情况下,在相应的变体参数中有VT_ERROR
、DISP_E_PARAMNOTFOUND
。
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 如何将内容数组写入文本文件?
- IDL文件和C++头文件中的defaultvalue和retval参数排序