2009-06-24 50 views
1

假设您执行以下操作:COM对象是否负责将自己的模块保存在内存中?

1)使用LoadLibrary加载foo.dll。

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

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

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

5)调用COM对象上的方法。

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

回答

2

我期待AV。即使它今天没有AV,这可能是一个等待发生的崩溃。

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

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

但是,没有什么能够阻止COM对象通过LoadLibrary递增DLL的引用计数 - 这样做没有任何违法或不安全。

4

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

+0

非常有趣。如果我们说在步骤3中调用的函数名为MyCreateInstance,答案会改变吗?即它是在CoCreateInstance之后建模的?谢谢! – 2009-06-24 23:29:16

+0

否。在上面的“标准”版本中,CoLoadLibrary调用维护对dll的引用 - 只有在安全的情况下才会释放该引用(通过查看对COM服务器中创建的对象的实时引用,或者在你的版本中,你需要确保你自己做到这一点 – 2009-06-24 23:36:31

相关问题