Any drawbacks in using LoadLibraryEx() instead of CoCreateInstance() for reg-free COM component consumption?
Our program needs to consume the COM server which is also made by开发者_JS百科 us. The scenario is the following: the installer will copy both the program files and the COM server files into the same folder on each install.
Currently we use regsvr32 to register the COM server, but this is not very good - if we develop another unrelated program that also consumes the same COM server (likely of another version) we can run into problems - since the CLSIDs are unchanged, the server registered later will be used by both programs and the first program might malfunction.
So we need reg-free COM. We could use manifests, but I've played with them for a while and find them not very convenient for use in the nightly build. We could also rewrite the program so that instead of calling CoCreateInstance()
it calls LoadLibraryEx()
, then GetProcAddress()
to locate DllGetClassObject()
and then just retrieves the class factory and uses it.
I immediately see some drawbacks:
- the program will have the dependency on the exact COM server filename
- extra code will have to be written for stuff normally managed by Windows
- the COM server will have to be in-proc and marshalling will never be used
and those drawbacks could be show stoppers generally but don't look bad at all in our specific scenario.
Are there any other drawbacks in using LoadLibraryEx()
/DllGetClassObject()
compared to CoCreateInstance()
?
I follow the exact procedure you describe, to implement my own lightweight version of COM. You are talking about replacing the 'activation' portion of COM. I think you list all the functionality the COM activation model provides:
- Out of process/apartment threading support
- Indirection via registry for resolving CoClass library location, allowing for newer versions, alternate implementations, etc.
Once you dynamically load the library, retrieve the class factory, and construct your object it should behave no differently than if you had created a in-process object within your apartment via COM.
1. the program will have the dependency on the exact COM server filename
By using DLL Delay-load notification hooks and handling dliNotePreLoadLibrary
(i.e. preempting the load), you can load from a DLL that has a different filename than recorded in the client's import table.
In fact, you can specify the actual DLL filename you wish to use in command line, or even a configuration file. (I just did that recently.) As long as you don't try to use the library before it's time.
2. extra code will have to be written for stuff normally managed by Windows
As for GetProcAddress
, The delay-load helper utility provides a function for loading all imports from a single module at once.
3. the COM server will have to be in-proc and marshalling will never be used
As for marshaling - I'm not familiar with this area, but here's some ideas:
- Need to implement your own proxy/stub code do handle inter-process-communication your own way
This means you'll need to write your own marshaling compiler, I'm afraid. You may find that other people have already done that.
Once that is done, the client will LoadLibrary
the proxy, the proxy will launch the stub executable (out-of-process) to host the server, and the stub will LoadLibrary
the actual server.
This is basically a complete reinvention of COM.
精彩评论