6

Is there ever a reason to use CoInitialize inside my DLL function when using IXMLDocument (msxml wrapper)? (or Other com object for that matter)

Is the calling application/thread responsible for calling CoInitialize/CoUninitialize?

What if I use ComObj inside my DLL which automatically calls CoInitialize in its initialization section and CoUninitialize in its finalization section?

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
zig
  • 4,524
  • 1
  • 24
  • 68

1 Answers1

8

Is the calling application/thread responsible for calling CoInitialize/CoUninitialize?

Yes. As a general rule, the creator of a thread must be responsible for initializing COM. Which means that the functions that you expose from your DLL should not initialize COM for the thread on which they were called.

The reason being that if you take responsibility for initializing COM in the thread that calls the DLL, then that places an unreasonable constraint on the creator of that thread. What if the creator of the thread needs to perform another action that requires COM to be initialized? The standard practise is that the DLL specifies COM initialization as one of its requirements. In the documentation for your DLL, state that the caller must initialize COM.

More details here: Things you shouldn't do, part 2: Dlls can't ever call CoInitialize* on the application’s thread.

That's why you should not initialize COM in your DLL on the caller's thread. There's even more reason not to initialize COM in an initialization section. Initialization sections are executed inside the DLL's DllMain. There are very few things that you are allowed to call inside DllMain, COM functions not being on the list of allowed actions. For more details: Some reasons not to do anything scary in your DllMain, part 3.

What if I use ComObj inside my DLL which automatically calls CoInitialize in its initialization section and CoUninitialize in its finalization section?

The ComObj unit does not do that. For a DLL, the COM initializing code that you refer to is suppressed. Including ComObj will force COM to be initialized in an executable project, but not in a library.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • But what if one of the units used by the DLL or the DLL itself uses indirectly "ComObj" unit? How should I tackle that if any? – zig Dec 17 '15 at 15:06
  • 1
    The more general rule here is: COM should only be initialized by the creator/owner of a thread. If the DLL creates its own threads to perform COM operations, it is responsible for initializing COM on those threads. – IInspectable Dec 17 '15 at 15:07
  • @zig Well, what if? There's no problem at all. The caller initializes COM, as instructed. And your DLL is fine to use the functions in `ComObj`. Using `ComObj` in a DLL does not cause COM to be initialized. That only happens in a GUI app. – David Heffernan Dec 17 '15 at 15:12
  • @DavidHeffernan Look at the initialization section of ComObj. Are you saying the initialization section is not used the DLL? – zig Dec 17 '15 at 15:20
  • 2
    Well yes. The code that adds to the init procs is protected with if not IsLibrary. Feel free to use `ComObj` in a DLL without initializing COM. I know I do. – David Heffernan Dec 17 '15 at 15:21
  • I missed the IsLibrary. Thanks! – zig Dec 17 '15 at 15:31