c++ - CoRegisterClassObject 破坏线程安全

标签 c++ com apartments

我正在测试将使用 coregisterclassobject 注册的自定义类工厂,我注意到它会导致线程问题。

我创建了一个测试 com 对象并创建了它的一个实例,一切都按预期运行。它是一个 inproc 服务器,在注册表中,它的 ThreadingModel 是“Apartment”。如果我用 apartment_threaded 调用 CoInitializeEx,它会在同一个线程上创建对象,如果我用 COINIT_MULTITHREADED 调用它,它会在一个单独的线程上创建它(因为它不能在多线程单元中创建)。

但是,如果我首先创建自定义类工厂的实例并将其注册到 coregisterclassobject,则该对象总是在同一个线程上创建,即使线程模型与线程的单元不匹配。我认为使用 coregisterclassobject 不会改变线程在多线程单元中而对象只能在单线程单元中的事实。

CoInitializeEx(NULL, COINIT_MULTITHREADED);
//CustomClassFactory *factory = new CustomClassFactory();
DWORD regNum = 0;
CLSID clsid = __uuidof(TestComObjLib::TestComObjCoClass);
//CoRegisterClassObject(clsid, factory, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regNum);
{
   TestComObjLib::ITestComObjPtr ptr;
   HRESULT hr = ptr.CreateInstance(clsid, NULL);
   if(ptr){
      auto str = ptr->HelloWorld();
      cout << str << endl;
   }
}
//CoRevokeClassObject(regNum);
CoUninitialize();

上面的代码按预期生成了新线程,但如果我取消对注释行的注释,COM 不会创建任何新线程。我的类(class)工厂没有做任何奇怪的事情。它只是加载 dll directyl 并调用 DllGetClassObject 来获取 com 定义的类工厂,并在其上调用 createinstance。对 HelloWorld 的调用仍然有效,但我只是不确定为什么线程不是我所期望的。

最佳答案

当您使用 CoRegisterClassObject 显式注册类工厂时,您将完全绕过注册表。即使注册表中根本没有提及该对象,它仍然可以工作。

由于从未查询过注册表,因此此处指定的线程模型无关紧要。您的对象被认为位于调用 CoRegisterClassObject 的单元中(或者更准确地说,IClassFactory::CreateInstance 将从该单元中调用;类工厂可能会耍花招获取它的对象实际上是在不同的公寓中创建的,然后编码回调用者)。

关于c++ - CoRegisterClassObject 破坏线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17624832/

相关文章:

c++ - 汇编程序消息:错误:拇指条件指令应放在IT block 中— `strexeq r1,r2,[r4]'

c++ - 添加新成员复制c-for/copy of-tor/序列化提醒

c++ - QtCreator 在 Windows 上的性能

matlab - 如何从 Matlab 调用 Excel 中的 Excel 宏?

c++ - 如何使用 COM 从 win32 应用程序处理 Excel 2007 和 Excel 2003(Excel 图表)?

c++ - ATL/COM : MIDL compiler doesn't output UUID for dispinterface

ActiveX 控件无法实例化,因为线程位于单线程单元中。将电脑从 sleep 状态唤醒后发生

c++ - std::mutex 线程间同步

delphi - 如何让控制台应用程序的主线程成为MTA?

c++ - 对于具有线程模型两者的对象,COM 编码是否(永远)是必需的?