我应该如何检查 COM 中的 [out] params 是否可以使用?

发布于 2024-07-19 02:10:59 字数 1126 浏览 14 评论 0原文

按照官方规定,除非函数成功,否则不应使用 COM 函数中的 [out] 参数,这意味着(至少)有三种方法可以查看 [out] 参数是否可以使用。

考虑以下界面

interface IFoo : IUnknown {
    HRESULT GetOtherFoo([out] IFoo** ppFoo);
    HRESULT Bar();
};

您建议使用以下哪种方式?

1. 检查返回值

CComPtr<IFoo> other;
HRESULT hr = foo->GetOtherFoo(&other);
if (SUCCEEDED(hr)) 
    other->Bar();

这让我有点紧张,因为 IFoo 中的错误可能会导致 NULL 指针取消引用。

2. 检查输出参数

这取决于这样一个事实:如果方法失败,则不得更改任何[out]参数(如果参数更改了<==>它是安全的使用它)。

CComPtr<IFoo> other;
foo->GetOtherFoo(&other);
if (other) 
    other->Bar();

请注意,无论如何都会发生这种情况,如果指针不是 NULL,CComPtr 的析构函数将调用 Release,因此它不可能是垃圾。

3. 偏执的方式,检查两者

CComPtr<IFoo> other;
HRESULT hr = foo->GetOtherFoo(&other);
if (SUCCEEDED(hr) && other) 
    other->Bar();

在我看来这有点冗长。


PS 请参阅相关问题

Officially one should not use [out] parameters from COM functions unless the function succeeded this means that there are (at least) three ways to see if an [out] parameter can be used.

Consider the following interface

interface IFoo : IUnknown {
    HRESULT GetOtherFoo([out] IFoo** ppFoo);
    HRESULT Bar();
};

Which of the following ways would you recommend on using it?

1. Check return value

CComPtr<IFoo> other;
HRESULT hr = foo->GetOtherFoo(&other);
if (SUCCEEDED(hr)) 
    other->Bar();

This makes me a bit nervous since a bug in IFoo could cause a NULL pointer dereferencing.

2. Check the output parameter

This depends on the fact that if a method fails it mustn't change any of the [out] parameters (if the parameter changed <==> it's safe to use it).

CComPtr<IFoo> other;
foo->GetOtherFoo(&other);
if (other) 
    other->Bar();

Note that this sort of happens anyway, CComPtr's destructor will call Release if the pointer isn't NULL so it can't be garbage.

3. The paranoid way, check both

CComPtr<IFoo> other;
HRESULT hr = foo->GetOtherFoo(&other);
if (SUCCEEDED(hr) && other) 
    other->Bar();

This is a bit verbose in my opinion.


P.S. See related question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜是你 2024-07-26 02:10:59

如果您愿意编写更多检查并使代码慢一点以使其更可靠,则选项 3 适合您。 由于您预计 COM 服务器中存在错误,因此检查它们是非常合理的。

If you are willing to write more checks and make code a bit slower for making it more reliable option 3 is for you. Since you expect that there are bugs in the COM server it is quite reasonable to check against them.

〃安静 2024-07-26 02:10:59

返回成功 HRESULT 但将某些输出参数设置为 NULL 的 COM 服务器方法并不常见。 有几种情况(我想到的是 IClientSecurity::QueryBlanket),但通常如果方法成功返回,客户端可能期望所有输出参数都为非 NULL。

毕竟,这是如何记录该方法的问题。 然而,在默认情况下,我认为 1. 是一种安全的方法。

COM server methods that return a success HRESULT, yet set some of their output parameters to NULL are not very common. There are a few cases (IClientSecurity::QueryBlanket comes to mind) where this is used, but usually the client may expect all output parameters to be non-NULL if the method returned successfully.

It is, after all, a matter of how the method is documented. In the default case, however, I would consider 1. to be a safe way to go.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文