【问题标题】:Are COM objects responsible for keeping their own module in memory?COM 对象是否负责将自己的模块保存在内存中?
【发布时间】:2009-06-25 05:36:23
【问题描述】:

假设您执行以下操作:

1) 使用 LoadLibrary 加载 foo.dll。

2) 使用 GetProcAddress 获取指向函数的指针。

3) 调用函数,为您提供对该模块中实现的 COM 对象的引用。

4) 通过调用 FreeLibrary 释放 foo.dll。

5) 调用 COM 对象的方法。

您是否希望第 5 步成功而 AV 不成功?也就是说,COM 对象本身是否负责(再次)调用 LoadLibrary 以增加 Windows 为每个模块保留的引用计数,以确保它不会超过模块?

【问题讨论】:

    标签: windows com


    【解决方案1】:

    当然不是。模块引用计数由正常的使用方法维护 - 您正在做的是运行时方案的后门。通常,您使用CoCreateInstance 等来创建您的对象 - 这些是调用CoGetClassObjectDllGetClassObject 的包装器。 CoGetClassObject 调用 CoLoadLibrary 维护 dll 的引用计数。此外,您可以在类对象上调用 LockServer 以维护类对象的引用计数以提高性能,但这并不是确保 dll 保持加载状态所必需的。

    【讨论】:

    • 非常有趣。如果我们说步骤 3 中调用的函数名为 MyCreateInstance,答案是否会改变? IE。它是在 CoCreateInstance 之后建模的吗?谢谢!
    • 没有。在上面的“标准”版本中,CoLoadLibrary 调用维护对 dll 的引用 - 只有在安全的情况下才会释放它(通过查看对 COM 服务器中创建的对象的实时引用,或者在调用 CoUninitialize。在您的版本中,您需要确保自己执行此操作。
    【解决方案2】:

    我希望有 AV。即使今天没有 AV,这也可能是等待发生的崩溃。

    对于这样的情况,COM 对象通过自定义 DLL 导出返回,我不希望 COM 对象增加 DLL 的引用计数 - 只要应用程序显式使用来自 DLL 的资源加载后,保持该 DLL 加载是应用程序的责任。

    对于通过普通 CoCreateInstance 路由创建的进程内 COM 对象,DLL 通常会导出 DllCanUnloadNow,只要存在未完成的引用,它就应该返回 S_FALSE。

    但是,没有什么可以阻止 COM 对象通过 LoadLibrary 增加 DLL 的引用计数 - 这样做没有任何非法或不安全的情况。

    【讨论】:

    • DLL 如何跟踪关于 DllCanUnloadNow 调用的未完成引用?谢谢!
    • 随心所欲。我见过每个 COM 对象的构造函数/析构函数递增/递减模块的全局引用计数的实现,而 DllCanUnloadNow 只是检查该引用计数。
    猜你喜欢
    • 2018-09-01
    • 1970-01-01
    • 2021-04-15
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 2018-07-31
    • 2021-11-15
    相关资源
    最近更新 更多