【问题标题】:Is passing NULL for COM interface arguments valid?为 COM 接口参数传递 NULL 是否有效?
【发布时间】:2015-10-09 22:49:55
【问题描述】:

如果我有一个需要 BSTR 和 SAFEARRAY 参数的 COM 接口方法,但这些是可选的,那么实现它的正确方法是什么?我可以传递 NULL 还是需要传递空字符串和零长度数组?或者我会更好地传递可以是 VT_EMPTY VT_BSTR / VT_ARRAY 的 VARIANT?

例如

Login([in]BSTR Name, [in]BSTR Password /*optional*/);
SendEmail([in]SAFEARRAY *To, [in]SAFEARRAY *Cc /*optional*/);

在这些示例中,Password 应该作为 NULL 还是 "" 传递? Cc 应该作为 NULL 传递,还是我需要创建一个长度为 0 的 SAFEARRAY,或者传递一个 VT_EMPTY 类型的 VARIANT...哪些是有效/明智的选项?

【问题讨论】:

  • 呃,“实现这个”?当然听起来你正在为调用它而烦恼。请准确。并发布方法的声明,这样我们就不必猜测了。
  • 我只是问你是否可以传递 NULL,或者必须传递“空对象”。这会影响 COM 实现知道要检查什么,对于可选参数。
  • NULLBSTR 的有效值,无论它是否被视为可选参数。我认为安全数组不是这种情况,那里应该有一个有效的指针。您可以将NULL 传递给数组和其他指针,如果实现直接接收调用,则它会工作,无需编组。然而,Marshaler 可能会在意外的NULLs 上失败。 defaultvalueoptional 仅适用于 VARIANTs。

标签: com


【解决方案1】:

嗯,这些参数确实不太正确——如果您尝试将除 VARIANT 之外的任何内容设置为“可选”,MIDL 编译器应该会抛出警告甚至错误。

正确的方法是定义默认值(“defaultvalue”)。对于 BSTR,您希望将默认值设为 L"" 而不是 0 (NULL)。如果您将 BSTR 的默认值设置为 0,那么您将遇到问题——我认为在某些 .NET 互操作中。

对于 SAFEARRAY,将“默认值”设为 NULL 应该是安全的。

当然,这个建议是从设计界面应该如何设计的角度出发的。您可能处于有人已经设计并实现了界面的情况。在这种情况下,您将受其实施的摆布。对于 BSTR 参数,我会尝试传入空字符串 (L""),对于 SAFEARRAY,我会尝试传入 NULL。

如果您要将其定义为“可选”,请将其设为变体。在这种情况下,正确的参数是 VT_EMPTY。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 2011-12-04
    • 1970-01-01
    相关资源
    最近更新 更多