开发者

The difference between traditional DLL and COM DLL

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开发者_JAVA技巧 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.


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.


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++.


I think by reading the first chapter of Essential COM by Don Box linked here, you'll have a very good idea of why we use COMs.

To summarize: COM ensures compatibility at the binary level, no matter what language you used, or what version 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."


If you want to learn about the reasons for introducing COM and the philosophy behind it, I strongly recommend reading From CPP to COM


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.


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.


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

  1. how to version your object across releases
  2. how to discover your object, even if your object is in a DLL that gets renamed or came from a different source
  3. how to reference and destroy your object (with respect to heaps)
  4. 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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜