可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am currently studying COM. I found that COM DLL is kind of built upon the traditional DLL infrastructure. When we build COM DLLs, we still rely on the traditional DLL export methods to lead us to the internal COM co-classes.
If COM is for component reusing at the binary level, I think the traditional DLL can achieve the same thing. They both expose functions, they are both binary, so what's the point of turning to COM approach?
Currently, I have the feeling that the traditional DLL expose methods in a "flat" manner, while the COM DLL expose methods in an "OOP" hierarchy manner. And the OOP manner seems to be a better approach. Could this be the reason why COM prevails?
Many thanks.
回答1:
No, there's a Big difference. COM has a well defined protocols for creating objects, exposing methods, managing memory, publishing type information, managing threading. There is practically no language left that doesn't support using a COM server, no matter what language it was written in.
You will not get that from exposing your own functions directly. That will likely be only usable from a program written in C/C++ (so it can read your header files), compiled with the exact same version of the C++ compiler and no lack of all kinds of interop problems. Something as simple as exposing a C++ class object like std::string is not safe. Neither the memory layout is guaranteed to be compatible, nor is there any kind of memory ownership protocol.
It could well be more OOPy, COM doesn't support inheritance because OOP is so hard to get compatible at the binary level. That problem requires runtime support that all code buys into, VMs like .NET and Java.
回答2:
A COM DLL is simply a DLL with Com-specific entry points. COM exposes class factories for creating com objects, so there needs to be a way of getting access to one of the class factories implemented by a COM server. That's what DllGetClassObject does. Furthermore, COM DLL's are self-registering: they can notify Windows of their available classes and interfaces. The Entry point for having the DLL register itself is DllRegisterServer.
There are a couple of other entry points, but they are along these lines.
If there wasn't a well-defined entry point for DllRegisterServer, then clients wouldn't be able to cause DLL's to self-register. It would make installation of COM components more complex.
If there weren't a standardized entry point for getting class factories, then each DLL would have to define its own entry point and that information would have to be put in the Windows Registry so that the COM infrastructure would know how to access each DLL's class factory. There's no justification for the extra complexity, so that entry point is also standarized.
As to where COM differs from 'C', the main difference is the concept of contracts. COM encourages programmers to think in terms of abstract interfaces between modules rather than a hierarchical, top-down decomposition of functionality. This is one kind of 'OOP', but that term is too loose to be of much use, IMO. Advantages of the contract-oriented approach are manifold for strongly-typed, statically linked languages like C/C++.
回答3:
I think by reading the first chapter of Essential COM you will have a very good idea of why using COM.
To be simple, COM ensure the compatibility in binary level, no matter what language you used, what version of compiler you used. It is not about the "OOP" thing, you sure could expose C++ class from a DLL, but they are not "binary compatible".
回答4:
If you want to learn about the reasons for introducing COM and the philosophy behind it, I strongly recommend reading From CPP to COM
回答5:
The key difference is that COM enables binary compatibility.
If you add/remove functions and rebuild a traditional DLL then any client applications will probably fail when they try and use the DLL because they were built against the earlier version.
COM introduced the concept of interfaces, which are immutable so should not be altered between builds, etc. Every COM object must implement the IUnknown interface which contains the QueryInterface method which is used to ask the object for pointers to other supported interfaces.
The COM specification ensures that the IUnknown interface is always in the same place in the DLL so even if an object is revised to support more interfaces the QueryInterface method can still be called safely.
回答6:
DLL has many uses in windows. Many types of library code are stored in DLL. One of these, for example, is .net assemblies, which is a different beast.
COM DLL is not better than "plain binary PE DLL" because COM DLL is also a plain DLL. What makes DLL a COM DLL is exposing, possibly in addition to other things, certain exports that match a certain contract (signature) [lookup entry IUnknown], or even several types of canonized interfaces [lookup entry 'dual interface'] that allow not only instantiation of specific objects inside the DLL but also automated discovery of services, including function names and parameter types.
The dual interfaces make it very handy to link to scripting languages (used in web, shell scripts, educational programs, etc) because the script programmers do not care about strict typing. A dual interface exposed by COM DLL allows the scripting runtime to query exactly what types it expects and do the appropriate casts, seamlessly to the user.
This flexibility allowed a whole gigantic COM infrastructure to be built upon, including Component Registration, DCOM (invocation over network), etc. It made it rather convenient to provide COM interfaces into windows components (WMI, for example) and office components. Many other popular interfaces were implemented above COM, such as ADO.
All this is good, but COM does not "prevail" in any sense. COM DLLs are minority of DLLs. Plain DLLs and .NET DLLs are very popular. Microsoft considers .net interfaces superior to COM. Many unix freaks and others consider DLLs to be a bad idea altogether, as it does not provide run-time linking services in the same sense that unix shared objects always had. Despite being a windows developer, I also think SOs provide a superior alternative, and I hope to have them once.
回答7:
The best way to think of COM is to imagine it as a contract between you and the person using the object you create.
COM handles
- how to version your object across releases
- how to discover your object, even if your object is in a DLL that gets renamed or came from a different source
- how to reference and destroy your object (with respect to heaps)
- how you expect threading to work, and the rules surrounding threading/locking for your object
COM has become a standard because while you could make a traditional DLL that handles each of the above items you'd have to articulate the expected contract when you ship your DLL
by using the rules of COM, this articulation is done for you
you are also correct that COM exposes objects while more traditional DLLS just expose functions. you'll often see developers try to emulate the contracts found in COM in straight C, usually you'll see them clone aspects of COM in their DLL (for example you'll see methods that return structs of function pointers)... my experience is if you dont use COM for making a public DLL you're increasing the odds of miss some cases, especially when versioning is in the picture
回答8:
In addition to the answers already posted, COM interfaces expose binary data objects in a programming language independent manner, that allows memory for these objects to be allocated in one process address space and freed in another. Lookup marshalling and unmarshalling.
It also allows strings to be passed without paying attention to details of encoding to determine where a null-terminator might be. COM strings are counted UNICODE strings.
Throw in IDL and compile the type library into the DLL, and you have self-describing interfaces. With plain DLLs, you have to know from the external docs what methods they have and the parameters they take.
The COM standard can be cross-platform, as well. Mac versions of Office support COM, and there have been implementations for Unix and Unix-like systems, although they have never been popular.