从标准 COM 接口方法返回未记录的 HRESULTS?

Posted

技术标签:

【中文标题】从标准 COM 接口方法返回未记录的 HRESULTS?【英文标题】:Returning undocumented HRESULTS from standard COM interface methods? 【发布时间】:2011-09-23 14:09:25 【问题描述】:

从记录的标准 COM 对象返回未记录的 HRESULTS 的规则是什么?

我正在查看IObjectWithSite.SetSite 的文档,其中说我应该在所有 情况下返回S_OK

语法HRESULT SetSite(IUnknown *pUnkSite);

参数 - pUnkSite: [在]指向管理此对象的站点的接口指针。如果为 NULL,则该对象应调用 IUnknown::Release 以释放现有站点。

返回值 在所有情况下都返回 S_OK。

这很好。但是我正在查看一篇 MSDN 文章,详细介绍了编写浏览器帮助程序对象,并且有他的代码为 IObjectWithSite.SetSite,它返回 S_OK 以外的 HRESULTS:

E_INVALIDARG 如果 pUnkSite 为 NULL E_INVALIDARG 如果 pUnkSite 不支持 IWebBrowser2 E_POINTER 如果 webBrowser 不支持 IConnectionPointContainer 其他情况下的事件连接结果(即S_OK
HRESULT CViewSource::SetSite(IUnknown *pUnkSite)

  // Retrieve and store the IWebBrowser2 pointer 
  m_spWebBrowser2 = pUnkSite; 
  if (m_spWebBrowser2 == NULL)
   return E_INVALIDARG;

  // Retrieve and store the IConnectionPointerContainer pointer 
  m_spCPC = m_spWebBrowser2;
  if (m_spCPC == NULL) 
   return E_POINTER;

  // Retrieve and store the HWND of the browser. Plus install
  // a keyboard hook for further use
  RetrieveBrowserWindow();

  // Connect to the container for receiving event notifications
  return Connect();

如果 pUnkSite 为 NULL,代码返回 E_INVALIDARG 的事实看起来像一个错误,文档特别说明该参数可以为 null。

文档没有提到任何其他 HRESULTS 作为可能的返回值 - 事实上它说S_OK 将在在所有情况下返回?

他们肯定不会是认真的;它们不能表示所有情况。正确的?如果由于有人拔出 RAM 棒而导致内存不足或内存保护故障怎么办?

从记录的标准 COM 对象返回未记录的 HRESULTS 的规则是什么?

【问题讨论】:

代码违反合约。它不仅仅是存储站点以供以后使用,而是立即使用它。这需要错误检查。它可能有效,COM 程序员永远不会忽略 HRESULT。你为什么不检查以确保。 在 Windows Explorer 和 Internet Explorer 加载我的 dll 的上下文中:我们得到的唯一调用是 IObjectWithSite.SetSite 【参考方案1】:

当您进行 COM 编程时,您通常是非常防御性的。因此,作为调用者,您在调用接口函数时使用著名的 FAILED 或 SUCCEEDED 宏(或所用语言中的等效宏)。

但是,当文档规定结果不重要时,建议不要检查结果。所以,作为来电者,我会这样做

...
myObject.SetSite(whatever);
...

而不是

...
if (FAILED(myObject.SetSite(whatever))) goto error;
...

请注意,这是非常具体的,因为 SetSite 是这样记录的。

如果我没有仔细阅读文档(如您所做的那样)并假设这是一个“常规的 hresult 返回”接口调用,我会使用 FAILED 宏。如果您退回任何未记录的东西,FAILED 无论如何都会抓住它,而且我还是很安全的。

【讨论】:

以上是关于从标准 COM 接口方法返回未记录的 HRESULTS?的主要内容,如果未能解决你的问题,请参考以下文章

从 Oracle 函数返回记录的标准方法是啥?

JDBC的结果集

在联合之后只返回一条记录

ABI是否还存在比HRESULT更多的错误信息?

从匹配记录中返回特定字段

PayPal 支付标准从移动设备返回 GET 而不是 POST,因此无法验证记录支付