views:

137

answers:

2

For example, in language X:

let x = CreateOject( "MyProgID" )
x.LateBoundCall()
x.Release()  // (or setting x to Nothing in VB-like language, etc)

What happens to the DLL MyProgID lives in? Does COM unload DLLs automatically?

EDIT

This is assuming that the code above is in an executable that does not expose any COM.

+2  A: 

you have to manually release the resources used by COM objects. they use a ref counter internally to keep the number of references to the component. if the component still has a refcounter > 0, then the dll will not unload and the resources will not be freed.

Derick Bailey
correct, but doesn't answer the question.
peterchen
+9  A: 

Yes, but not in a deterministic way. Windows periodically asks every loaded DLL "is it safe to unload you now?" Any DLL that responds "Yes" is unloaded.

Note a remark from MSDN :

If a DLL loaded through a call to CoGetClassObject fails to export DllCanUnloadNow, the DLL will not be unloaded until the application calls the CoUninitialize function to release the OLE libraries.

See this Old New Thing article.

John Dibling
DLLs don't call `CoUninitialize`
wqw
@wqw: Wrong. According to MSDN: "To close the COM library gracefully on a thread, each successful call to CoInitialize or CoInitializeEx, including any call that returns S_FALSE, must be balanced by a corresponding call to CoUninitialize." http://msdn.microsoft.com/en-us/library/ms695279(VS.85).aspx
John Dibling
COM Library = the Win32 API library supporting COM runtime != the COM DLL. --- COM Server DLL's typically don't call CoInitialize (nor CoUninitialize) except on threads they create and manage themselves. Also, the typical implementation for `DllCanUnloadNow` just depends on the number of existing instances.
peterchen
@peterchen: Yes, COM server DLLs do call CoInitialize(). At least they should. If the application that uses the COM server DLL doesn't itself use COM, and no other code in the same thread where the DLL was loaded uses COM, then COM won't be initialized.
John Dibling
John, I don't consider the typical case "pedantical". COM Server DLL's are normally loaded through CoCreateInstance --> CoGetClassObject --> ... which requires COM libraries to be initialized already. If the DLL only consumes but does not expose COM objects, it's not a COM Server DLL (well, ok, that last one *is* close to nitpicking)
peterchen
@Peter: Sorry, my context switcher was all messed up and I was thinking in terms of a consumer, not a provider, but writing in terms of a provider. You (and wqw) are right that a provider should not normally need to CoUninit(). I'll update my response.
John Dibling
@John, no problem ;) - upvoted you again
peterchen