tags:

views:

311

answers:

7

Assume that you work only in the C++ world (cross-language interop is not required). What advantages/inconvenients do you see in using COM instead of a plain basic DLL? Do you think using COM is worth the trouble if you are not going to use the interface from different languages?

+4  A: 

COM can be useful in plain old C++ for:

  • Interprocess communication
  • Plugin architectures
  • Late binding scenarios
  • "Much, much, more..." (tm)

That said, if you don't need it, don't use it.

consultutah
Yeah totally agree - unless you need it, it is often more trouble.
stephbu
Amen. COM and the technologies that go with it were a big stepping point between OLE and where we are now, but not something that you'd want to backtrack to unless you can't avoid it. The primary difficulty of COM is that you will find yourself doing by hand things that other solutions resolve in the background.
quillbreaker
+1  A: 
  • Registration and discovery
  • Out-of-process
  • Remote invocation

are the few extra features that you would have got. Even transactional support can flow without the need for COM support these days.

stephbu
+1  A: 

The IUnknown interface is a good base level to support anyway -- gets you a way to add features without breaking old clients (QueryInterface) and pervasive reference counting. You can implement this without buying into everything in COM.

Then, whenever you are adding a feature to a class, if you use the COM interface for it, you at least get an interface that is known -- for example IDispatch if you want reflection features.

Your only delta away from being able to be called by another language would then be the registration and the class factory.

Lou Franco
+4  A: 

With DLL you can get much closer coupling, while COM limits interactions very precisely. This is the root of both the advantages and the disadvantages!

You get more power and flexibility (e.g. inherit from classes defined in the DLL, not feasible in COM) but the dependency is thereby much stronger (need to rebuild the user for certain changes to the DLL, etc).

Often especially galling is that all DLLs and the EXE must use the same kind of runtime library and options (e.g. all dynamically linked to the non-debug multithreaded version of msvcrt* for example -- can't rebuild just one to use the debug version without incurring very likely errors!).

The looser coupling of COM is therefore often preferable, unless you really need the closer-coupling kinds of interactions in a specific case (e.g., a framework, which definitely requires user-code to inherit from its classes, should be a DLL).

Alex Martelli
+1  A: 

Because interfaces are independent of any particular DLL, at its simplest level, a COM like approach at the very least frees you to change the dll serving an interface under the hood, without having to recompile your app against the new dll name.

Using Full COM with MIDL defined interfaces and proxy stub dlls means that you can use COM to manage thread safety in-process, interprocess comms on the same PC, or even connect to the COM server object on a remote PC.

Chris Becke
Not really true. If you don't change the function definition and only change the implementation you don't have to recompile your app -- just the DLL. If you do change the signatures of functions, then you would need to recompile whether you use straight DLLs or COM.
John Dibling
I meant. changing the name of the dll, not the function. COM decouples the modules so, a few years into your app design, youre not locked to maintaining a.dll, b.dll and c.dll. You can freely merge the COM objects into larger dlls, or split them out more as your applications evolving needs require.
Chris Becke
+5  A: 

Everybody is mentioning things that are in COM's plus column. I'll mention a couple of detractions.

  • When you implement your system using COM, you need to register the COM 'servers' (be they in-proc or out-of-proc) at setup and unregister them at uninstall. This could increase the complexity of your setup system slightly and tends to require a reboot unless the user carefully tears down running processes first.

  • COM is slow compared to other standard ways of doing the same thing. This comment will probably generate a lot of hate and maybe some downvotes, but the fact of the matter is that at some point you will need to marshall data, and that is expensive.

  • According to the Rules of COM, once an interface has been published it can never be changed. That in itself is not a negative, and you might even argue that it forces you to do thorough design before shipping the interface. But the truth is there's no such thing as never, and in production code interfaces change. You will undoubtedly need to either add methods or change the signatures of existing methods. In order to accomplish this you have to either break the rules of COM -- which has bad effects -- or follow the rules of COM which are more complicated than just adding a parameter to a function like you would with a astraight DLL.

John Dibling
> COM is slow compared... < I disagree. COM is only "slower" when "activating" or "instanciating". Once the object is created, it's as fast as anything else you can come up with. Whether activation/creation time is important depends on the specifics of the problem. Also, COM is slower in calls only if you cross apartments, which you should do only if you "need it" (in which case you will "need" similar slow-downs under any other alternative aproach). Performance is usually not a reason not to use COM.
Euro Micelli
+1  A: 

If you can avoid don't use it. In my last project COM brought pretty much limitations into C++ interfaces being used. Just imagine, that you can't simply pass a std::string but have to use an array of characters. In that case you build the string, an then copy it to an array which can be handled by COM.

You also can only use very limited set of fundamental types, have casts and proprietary memory management. You can't use new/delete, but have to use COM own functions.

You also can't simply throw an exception, but have to initialize some COM interface IErrorInfo, which will be rethrown at the other end.

So if you don't need, don't use it. It will definitely screw your design. And if you need it, try to evaluate other interop possibilities: boost::interprocess, zeroc ice...

Regards,

Ovanes

ovanes
Here's a suprise: if you use DLLs you could have the same trouble passing around std::string's as well. The only way to avoid it is to use the same compiler for the DLL and the client code. More specifically, the same implementation of std::string.
John Dibling
Yes I know it. We used the same compiler for all projects. But the described std::string problem might be of different nature as well. When you use different implementations of standard lib accross your project, even with the same compiler.
ovanes