- Some implementations calls
DllAddRef()
andDllRelease()
in theCClassFactory
constructor, destructor, andLockeServer
member function:
https://github.com/microsoft/workbooks/blob/master/Clients/Xamarin.Interactive.Client.Windows.ShellExtension/ClassFactory.cpp - Some do it only in
LockeServer
:
https://github.com/microsoft/Windows-classic-samples/blob/main/Samples/CredentialProvider/cpp/Dll.cpp - And in others, the
CClassFactory
constructor and destructor use a totally different reference count variable from that ofLockeServer
:
https://github.com/microsoft/Windows-classic-samples/blob/main/Samples/NetworkAccessProtectionExtensions/cpp/SampleShvUi/shvuicf.cpp
Which one is the right way? Also the use of global reference count variables seems like a rather outdated pattern. Could static class member variables be used instead?
CodePudding user response:
COM makes a distinction between DLL reference counting and object server reference counting.
Sometimes the object server is exactly one DLL and no more and it makes sense to combine them, sometimes the object server needs to maintain additional state (open files, network connections) and therefore requires different lifetime.
There's no disadvantage to using global variables for the DllAddRef
and DllRelease
reference counts -- those functions have to be global anyway so there's no possibility of having a class to store per-instance data.
And the globals will tend to be declared static
in a single compilation unit -- that means no linkage and less work for the linker to do. Since these functions are called via LoadProcAddress
there's no lost opportunity for inlining them (inlining would require linkage so the variables can be found at all call sites).
In contrast, CClassFactory
reference counts will tend to be stored in the CClassFactory
class instance, which typically will be a singleton but there's no prohibition on advanced COM scenarios like tearoffs.