small text    normal text    large text
EVE-Online - New Universe, New Rules
NO2ID - Stop ID cards and the database state

You are here: home > articles > comprog

Unloading a COM DLL

13th November 2005, 20:00

When does a COM DLL unload from a process? Until this week, I thought the answer was straightforward; a COM DLL is unloaded when all instantiated COM objects within the DLL had been deleted (i.e. their reference counts had decreased to zero) and the DLL's implementation of DllCanUnloadNow() returns S_OK when the COM Library is destroyed by CoUninitialize(). But that's not always the case...

I recently had a process that dynamically loaded a simple plugin DLL. In a new thread the plugin in turn created a COM object via a standard CoCreateInstance() call. The object was used, released, and CoUnitialize() called... but the COM DLL didn't unload.

I debugged into the COM object and verified that the reference count was zero after releasing, the object was deleted, and that DllCanUnloadNow() was indeed returning S_OK. I then set up a loop that every second would call CoFreeUnusedLibraries() and, after exactly ten minutes, the DLL would unload. This must be the infamous 'ten-minute unload delay' I'd read about. After a few wasted hours I changed the DLL's threading model from Both to Apartment and, hey presto, the DLL would now unload! But this was a change that couldn't be justified - it could somehow impact on numerous customers.

I eventually discovered that the COM DLL wasn't being unloaded immediately because firstly it was a multithreaded object, and secondly there was a pending CoUnitialize() in the process itself! I'd already unloaded the COM Library from the plugin DLL, but had no control over the process. Normally COM unloads a DLL when CoUnitialize() is called, but couldn't in this case until ten minutes had elapsed.

(The solution? Well, it was imperative that the DLL isn't left loaded for ten minutes, that just isn't viable. And we couldn't use the Apartment threading model for the COM DLL, too great a change with too much potential risk. Instead of using a plugin DLL we now spawn a new process that simply creates the COM object. An overly complicated solution, but what the heck...)


Copyright © Cyotec Systems, 2003-2008. All rights reserved.