我的COM对象有一个方法,在IDL中定义为:
HRESULT _stdcall my_method( [in] long value, [in, out] IAnotherObject **result );
是否允许调用者像这样调用此方法:
ptr->my_method(1234, NULL);
或者调用者是否会违反COM规范?
换句话说,我的代码实现此功能是否应该在继续之前检查result != NULL
;如果是这样,COM规范是否要求我返回E_INVALIDARG或E_POINTER或其他东西;或者我的函数是否可以继续并返回0
而不分配AnotherObject?
我的目标是与自动化兼容;它使用标准编组。
注意:自原始文字以来编辑的问题。发布此问题后,我发现optional
should only be used for VARIANT和[in, out]
参数result != NULL
但*result == NULL
should be treated like an out parameter, and I must allocate an object。
答案 0 :(得分:1)
The Rules of the Component Object Model说:
输入输出参数最初由调用者分配,然后在必要时由被调用者释放和重新分配。与out参数一样,调用者负责释放最终返回值。必须使用标准的COM内存分配器。
因此,传递NULL
是违规行为。即使在Microsoft自己的接口中也可以看到几个违反COM规则的行为,例如IDispatch
,其中一些[out]
参数接受NULL
,但这是因为它们具有远程接口方法(请参阅{{ 3}}和[local]
)最有可能在穿越公寓时分配所需的内存,或以其他方式执行自定义编组。
编辑:进一步回答你的问题。
我建议您检查NULL
[out]
(或[in, out]
)个参数,并在找到时返回E_POINTER
。这将允许您提前捕获/检测最常见的错误,而不是引发访问冲突。
答案 1 :(得分:1)
是的,你应该检查参数的有效性。
如果客户端与服务器在进程中(和同一个公寓等),则没有任何内容(没有代理,没有存根)来保护您的代码不被NULL调用。
因此,您是唯一一个执行任何COM规则的人,无论是否被视为“违规”。
PS:为自动化客户端定义输入+输出(不使用VARIANT)似乎有点不寻常恕我直言。我不确定所有自动化客户端都可以使用它(VBScript?)