COM中的NULL in / out参数

时间:2014-07-01 23:32:09

标签: com

我的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

2 个答案:

答案 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?)