【问题标题】:Does the caller need to Release the IShellBrowser* obtained via the undocumented WM_GETISHELLBROWSER (WM_USER+7) message?调用者是否需要释放通过未记录的 WM_GETISHELLBROWSER (WM_USER+7) 消息获得的 IShellBrowser*?
【发布时间】:2009-12-15 19:40:44
【问题描述】:

一些人指出,存在一条未记录的消息,该消息从文件打开和保存对话框的通用对话框 HWND 中检索 IShellBrowser 接口指针。

但是关于该指针是否是 AddRef'd,或者它是否只是返回的原始地址,并且不应该调用 Release(),存在冲突的信息(或没有信息)?

【问题讨论】:

    标签: c++ winapi openfiledialog


    【解决方案1】:

    没有。您可能会发现以下链接很有用:The Rules of the Component Object Model

    摘录:

    引用计数规则

    规则 1:必须调用 AddRef 界面的每个新副本 指针,并为每个释放调用 接口指针的破坏, 除非后续规则 否则明确允许。

    以下规则很常见 规则 1 的非例外情况。

    • 规则 1a:函数的输入输出参数。调用者必须 AddRef 实际参数,因为当输出值存储在它上面时,它会被调用者释放。
    • 规则 1b:获取全局变量。从全局变量中指针的现有副本中获取的接口指针的本地副本必须独立进行引用计数,因为调用的函数可能会在本地副本仍然存在时破坏全局中的副本。
    • 规则 1c:“凭空”合成的新指针。使用特殊内部知识而不是从其他来源获得接口指针的函数必须对新合成的指针执行初始 AddRef。此类例程的重要示例包括实例创建例程、IUnknown::QueryInterface 的实现等。
    • 规则 1d:返回内部存储指针的副本。在指针被返回后,被调用者不知道它的生命周期与内部存储的指针副本的生命周期有何关系。因此,被调用者必须在返回指针副本之前调用 AddRef。

    规则 2:零件的特殊知识 的一段代码 开端的关系和 两个或两个生命的终结 接口指针的更多副本 可以允许 AddRef/Release 对 省略。

    • 从 COM 客户端的角度来看,引用计数始终是每个接口的概念。客户不应假定一个对象对所有接口使用相同的引用计数。
    • 不应依赖 AddRef 和 Release 的返回值,而应仅用于调试目的。
    • 指针稳定性;请参阅 OLE 帮助文件中“引用计数规则”下的“稳定 this 指针并保持其有效”小节中的详细信息。

    查看优秀的“管理对象” OLE 中的生命周期”技术文章,作者 道格拉斯霍奇斯和第 3 章 OLE 内部,第 2 版,作者 Kraig Brockschmidt(MSDN 图书馆,书籍) 更多信息 引用计数。

    【讨论】:

    • 对不起 - 我感觉有点厚。但是您的第一个陈述是“否”,因为我不需要 release() 返回的 IShellBrowser* - 但是规则 1 的文档(尤其是它的非例外)似乎表明我的指针我会代表我进行 AddRef(就像 QueryInterface 所做的那样)。
    • 您可以根据需要在该对象上手动调用 AddRef() / Release(),如规则 1c 中所述(want 我的意思是对象的生命周期由窗口管理经理)。但是您不需要只需要调用 Release()。
    • 所以你的理解是这是一个特例 1c(根据 1c 的标题,我可以看出这有什么意义)。如果是这种情况,1c 基本上说它既不是 out 参数,也不是 in 参数,也不是 inout 参数,而是一个综合参数,因此需要由调用者进行 AddRef 和 Released (或者,显然这里的情况是这样,除非我尝试将指针保持的时间长于当前 IShellBrowser 的生命周期,这在我的自定义 OPENFILEDIALOG 处理程序中不会发生)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 2013-05-03
    相关资源
    最近更新 更多