COM& CoGetClassObject()

时间:2011-07-20 14:28:16

标签: c++ com

CoGetClassObject()我有点问题。

我有一个必须使用特定版本的DLL的应用程序, 但它们也存在于系统中,在更新的版本中。

所以我开始挂钩CoCreateInstance()loadLibrary(),我觉得这很好。 问题是两个版本中的DLL都已加载。

所以我认为CoGetClassObject()是问题/解决方案,因为它提供了指向与包含应用程序必须在旧版本中使用的DLL的CLSID关联的对象的接口的指针。

但我不知道这个功能“做什么”,那么如何“覆盖”这个功能呢?

感谢。

PS:我是COM编程的新手。

3 个答案:

答案 0 :(得分:4)

CoGetClassObject()只执行CoCreateInstance()所做工作的一半。它返回一个类工厂。然后CoCreateInstance()调用IClassFactory :: CreateInstance()并释放IClassFactory。如果您需要创建某个coclass的许多对象并希望对其进行优化,则只能使用它。它避免了一次又一次地创建和发布工厂的成本。

您可能忽略了解决此问题的简单方法。您只需将新版本的COM服务器DLL复制到与客户端EXE相同的目录中即可。并创建一个名为“app.exe.local”的零字节文件,其中“app”是EXE的名称。这足以强制加载复制的DLL而不是注册表指向的DLL。 MSDN Library有关DLL重定向的文章is here

答案 1 :(得分:0)

非常简单的解释是CoGetClassObject()打开HKCR\CLSID\{ClassId}并查看InProcServer32LocalServer32,具体取决于传递的CLSCTX_*值 - 即COM服务器路径。

一旦发现COM服务器文件路径被加载(LoadLibraryEx()在进程中为LOAD_WITH_ALTERED_SEARCH_PATH标志,或在出...的情况下为CreateProcess())COM服务器。然后它为进程内服务器找到并调用DllGetClassObject()或等待直到为out-proc服务器注册类工厂。

这当然忽略了DCOM等内容。您可以使用Process Monitor实用程序更好地了解它如何遍历注册表。

答案 2 :(得分:0)

如果要加载特定的COM DLL,无论是否安装了较新的版本,并且无论旧版DLL位于何处,都只需完全忽略CoCreateInstance()CoGetClassObject()。通过LoadLibrary()自行加载旧DLL,然后直接调用其导出的DllGetClassObject()函数以获取DLL的IClassFactory接口,然后根据需要调用IClassFactory::CreateInstance()。无论如何,这都是CoCreateInstance()CoGetClassObject()内部执行,但这会绕过他们执行的注册表查找,以确定要加载的DLL路径。