C++ CoreRegisterClassObject不';不能使用从另一个线程封送的类工厂

C++ CoreRegisterClassObject不';不能使用从另一个线程封送的类工厂,c++,com,apartments,C++,Com,Apartments,我试图使用CoreRegisterClassObject来定制加载包含com对象的dll的方式。我正在尝试解决线程的单元类型与com对象的单元类型不匹配时遇到的问题。我遇到了一个问题,coregisterclassobject返回S_OK,但似乎没有做任何事情,因为com对象仍然依赖于要创建的注册表。下面是我编写的一个示例,作为失败的概念证明(TestComObj是单元线程) 这是我主要功能的相关部分 CoInitializeEx(NULL, COINIT_MULTITHREADED); HA

我试图使用CoreRegisterClassObject来定制加载包含com对象的dll的方式。我正在尝试解决线程的单元类型与com对象的单元类型不匹配时遇到的问题。我遇到了一个问题,coregisterclassobject返回S_OK,但似乎没有做任何事情,因为com对象仍然依赖于要创建的注册表。下面是我编写的一个示例,作为失败的概念证明(TestComObj是单元线程)

这是我主要功能的相关部分

CoInitializeEx(NULL, COINIT_MULTITHREADED);

HANDLE regThread = CreateThread(NULL, 0, FactoryThread, NULL, 0, NULL);
Sleep(5000); //ensures that the factory is registered

IClassFactory *factory = NULL;
CoGetInterfaceAndReleaseStream(factory_stream, IID_IClassFactory, (void**)&factory);

DWORD regNum = 0;
HRESULT res = CoRegisterClassObject(clsid, factory, CLSCTX_INPROC_SERVER, REGCLS_MULTI_SEPARATE, &regNum);
//res == S_OK
{
   TestComObjLib::ITestComObjPtr ptr;
   HRESULT hr = ptr.CreateInstance(__uuidof(TestComObjLib::TestComObjCoClass), NULL);
   //hr == E_NOINTERFACE HERE if not registered in the registry
}
CoRevokeClassObject(regNum);
CoUninitialize();
其想法是,由于注册表不应与CoRegisterClassObject一起使用,因此我需要在STA中手动创建单元线程对象,而不是当前MTA线程。我注意到,当不使用CoreRegisterClassObject时,CoGetClassObject会生成一个新线程并在该线程中调用DllGetClassObject,因此我认为只需要在STA中创建类工厂,然后对象就会存在于其中


我看到的问题是,在上面的代码中,它仍然使用注册表创建TestComObj,即使类工厂的行为正常。现在很简单。它只是在正确的dll上调用LoadLibrary,然后调用dllgetclassobject,并在结果上调用createinstance。当不处理单元和线程问题时,我可以使用它创建com对象,而无需注册它。因此,我不确定这里出了什么问题。

CoMarshalInterThreadInterfaceInStream的反义词是
CogetInterface and LeaseStream
,而不是
ConmarshalInterface
。不管怎样,你为什么要抽调呢?为什么不直接从FactoryThread注册呢?哎呀,我以前把它当作CogetInterface和LeaseStream使用过,但我尝试过其他东西。但两者都不起作用。我相信每个线程都需要调用CoreRegisterClassObject。我尝试在FactoryThread中调用它,但发现类未注册错误。我99%确定
CoRegisterClassObject
在一个进程中只需要调用一次。在您的代码中,
clsid
(您传递到
CoRegisterClassObject
)和
\uuidof(TestComObjLib::TestComObjCoClass
(您传递到
CreateInstance
)之间的关系是什么?我注意到这两种情况之间的一个区别是“类未注册vs E_NOINTERFACE。这些CLSID是相同的。
CoInitializeEx(NULL, COINIT_MULTITHREADED);

HANDLE regThread = CreateThread(NULL, 0, FactoryThread, NULL, 0, NULL);
Sleep(5000); //ensures that the factory is registered

IClassFactory *factory = NULL;
CoGetInterfaceAndReleaseStream(factory_stream, IID_IClassFactory, (void**)&factory);

DWORD regNum = 0;
HRESULT res = CoRegisterClassObject(clsid, factory, CLSCTX_INPROC_SERVER, REGCLS_MULTI_SEPARATE, &regNum);
//res == S_OK
{
   TestComObjLib::ITestComObjPtr ptr;
   HRESULT hr = ptr.CreateInstance(__uuidof(TestComObjLib::TestComObjCoClass), NULL);
   //hr == E_NOINTERFACE HERE if not registered in the registry
}
CoRevokeClassObject(regNum);
CoUninitialize();