C++ COM&;CoGetClassObject()

C++ COM&;CoGetClassObject(),c++,com,C++,Com,我对CoGetClassObject()有点问题 我有一个应用程序必须使用特定版本的DLL, 但它们也存在于系统中,在一个较新的版本中 所以我开始挂接CoCreateInstance()和loadLibrary(),我想这很好。 问题是两个版本中的DLL都已加载 因此,我认为CoGetClassObject()是问题/解决方案,因为它提供了一个指向对象接口的指针,该对象与包含DLL的CLSID关联,应用程序必须在旧版本中使用该DLL 但是我不知道这个函数“做什么”,那么我如何“重写”这个函数呢

我对
CoGetClassObject()
有点问题

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

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

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

但是我不知道这个函数“做什么”,那么我如何“重写”这个函数呢

谢谢


PS:我是COM编程新手。

非常简单的解释是
CoGetClassObject()
打开
HKCR\CLSID\{ClassId}
并查看
InProcServer32
LocalServer32
,这取决于传递的
CLSCTX.*
值-即COM服务器路径

一旦找到COM服务器文件路径,将加载COM服务器(
LoadLibraryEx()
with
LOAD\u with\u ALTERED\u SEARCH\u path
标志,如果是in-proc,或
CreateProcess()
如果是out-proc)。然后,它为进程内服务器定位并调用
DllGetClassObject()
,或者等待,直到为进程外服务器注册了类工厂

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

CoGetClassObject()只完成CoCreateInstance()的一半工作。它返回一个类工厂。CoCreateInstance()然后调用IClassFactory::CreateInstance()并释放IClassFactory。只有在需要创建某个类的多个对象并希望对其进行优化时,才能使用它。它避免了一次又一次创建和发布工厂的成本


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

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

感谢您的回复。但是添加.local文件并没有改变任何东西。所以我从CoGetClassObjectHooked()调用了CoCreateInstance(必须由我的CoCreateInstanceHooked钩住)和CreateInstance(NULL,riid,ppv),但最后返回的是一个E_NOINTERFACE。提示的要点是根本不做任何钩住。只是让它自动加载复制的DLL。无聊但有效。是的,我没有钩住,我只是添加了.local文件。但这两个版本都加载了。让我们关注更大的谜团。这怎么可能呢?COM服务器必须注册才能使用。具有相同注册表项的两个不同版本不能共存,最后一个注册的版本将覆盖第一个版本的注册。这意味着第一个永远找不到。你的程序中发生了什么?可能是因为我想在次要版本中使用的DLL是“受保护的”?这也绕过了并不总是好的封送和线程模型。我想这是我已经做过的。在CoCreateInstanceHook()和CoGetClassObjectHook()中,我只是这样做:
module=loadLibraryreal(lib);dllGetClassObject=(FUNC)GetProcAddress(模块,“dllGetClassObject”);hr=dllGetClassObject(rclsid、IID_IClassFactory和pClassFactory);hr=pClassFactory->CreateInstance(NULL,riid,ppv)它似乎在CoCreateInstane()中工作,但在CoGetClassObject()中我得到了一个E_NOINTERFACE