1

I am trying to register a custom class factory with CoRegisterClassObject, and the factory needs to be able to handle both STA and MTA objects. I'm noticing that IClassFactory::CreateInstance uses whatever threading model is specified for the current thread by CoInitializeEx. Is there a way to create the object in a different apartment and somehow marshal it back to the current apartment? For example,

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();

If TestComObjCoClass needs to be single threaded, I want to be able to do something in CustomClassFactory::CreateInstance that can create the object in a STA and marshal it to the current thread, which is in the MTA.

bdwain
  • 1,665
  • 16
  • 35
  • You're going about it the wrong way. If your object needs to be STA always, you need to mark it as such in the registry (e.g. HKCR\CLSID\{...}\InprocServer32:ThreadingModel = Apartment). COM will take care of the details, such as marshalling the object to the caller's apartment as needed. – Euro Micelli Jul 15 '13 at 19:29
  • I'm aware of the ThreadingModel attribute. I'm trying to make a custom class factory that can avoid the registry though. – bdwain Jul 15 '13 at 19:35
  • I'm confused. If you want the created object to always live in an STA apartment, why don't you simply arrange for `CoRegisterClassObject` to be called from an STA apartment? – Igor Tandetnik Jul 15 '13 at 19:36
  • I'm creating a custom class factory to work with an existing code base and set of com objects so I can avoid using the registry. In situations where you try to create an apartment threaded object in threads that are initialized as multithreaded or vice versa, COM would create the object in a separate thread and marshal the object back to your current thread (as opposed to just creating it in the calling thread). I want to have this behavior in my class factory. – bdwain Jul 15 '13 at 19:53
  • 1
    Just register your class factory in the thread that has joined the apartment you want your objects to live in. Create that thread if necessary. That's what COM runtime normally does, after reading the threading model from the registry. – Igor Tandetnik Jul 15 '13 at 20:44

0 Answers0