tags:

views:

75

answers:

2

Say you do the following:

1) Load foo.dll using LoadLibrary.

2) Get a pointer to a function using GetProcAddress.

3) Invoke the function, giving you a reference to a COM object implememented in that module.

4) Free foo.dll by calling FreeLibrary.

5) Call a method on the COM object.

Would you expect that step 5 succeeds and doesn't AV? That is, is the COM object itself responsible for calling LoadLibrary (again) to increment the reference count that Windows keeps for each module, ensuring that it doesn't outlive the module?

+4  A: 

Certainly not. The module reference count is maintained by the normal methods of use - what you are doing is a backdoor into the runtime scheme. Normally, you use CoCreateInstance and so on to create your objects - these are a wrapper around calling CoGetClassObject and DllGetClassObject. CoGetClassObject calls CoLoadLibrary which maintains a reference count on the dll. Additionally, you can call LockServer on the class object to maintain a reference count on the class object for performance, but this is not required to ensure that the dll remains loaded.

1800 INFORMATION
Very interesting. Does the answer change if we say that the function called in step 3 is named MyCreateInstance? I.e. it's modeled after CoCreateInstance? Thanks!
No. In the "standard" version above, the CoLoadLibrary call maintains the reference to the dll - this will be released only when it is safe to do so (by looking at the live references to objects created in the COM server, or in the event that CoUninitialize is called. In your version, you would need to make sure you do that yourself.
1800 INFORMATION
+2  A: 

I'd expect an AV. Even if it didn't AV today, this is probably a crash waiting to happen.

For a case like this, where a COM object is returned via a custom DLL export, I would not expect the COM object to increment the reference count of the DLL - as long as the application is using resources from a DLL it explicitly loaded, it's the application's responsibility to keep that DLL loaded.

For in-proc COM objects that are created via the normal CoCreateInstance route, the DLL will typically export DllCanUnloadNow, which should return S_FALSE as long as there are outstanding references.

However, there is nothing preventing the COM object from incrementing the DLL's reference count via LoadLibrary - there is nothing illegal or unsafe about doing so.

Michael
How does the DLL track the outstanding references in regards to the DllCanUnloadNow call? Thanks!
However it wants. I've seen implementations where the constructor/destructor for each COM object increments/decrements a global reference count for the module, and DllCanUnloadNow just checks that ref count.
Michael