From Microsoft website (its not about hot to write COM objects, but an good explanation of why its important to do it, sorry if its very large but i think is important):
---------------------------------------
If you've used Visual Basic much, you're very familiar with using components to do your programming: you use both visual ActiveX controls (such as spin buttons) and nonvisual ActiveX components (such as database access objects). It's hard to find a significant Visual Basic program that doesn't make heavy use of premade reusable components. But although you reuse plenty of components, most folks don't yet write a whole lot of reusable components of their own.
If you're programming in C++, you likely have a different experience of reuse. C++ and object-oriented programming claim to make reuse easy, but what has your experience been? Have you been able to create a library of reusable objects? A few of you no doubt have, but most of us have not. And if we have such a library, do we routinely make good use of it? It's not just a lack of discipline that keeps us from reusing our code: the fact is that it's hard to reuse code (it never seems to do quite what we need) and it's even harder to write reusable code (it's very hard to be general enough yet useful enough).
On top of that, what C++ makes easy is not creation of reusable binary components; rather, C++ makes it relatively easy to reuse source code. Note that most major C++ libraries are shipped in source form, not compiled form. It's all too often necessary to look at that source in order to inherit correctly from an object?and it's all too easy (and often necessary) to rely on implementation details of the original library when you reuse it. As if that isn't bad enough, it's often tempting (or necessary) to modify the original source and do a private build of the library. (How many private builds of MFC are there? The world will never know . . .)
So let's reuse binary objects, not source code
So how can you reuse binary objects? Well, the answer that first comes to a Windows programmer's mind is simple: use dynamic-link libraries (DLLs). Using DLLs does work?Windows is itself, after all, primarily a set of DLLs. But there are some problems.
First, DLLs are not necessarily programming-language independent. Even for DLLs written in C, it's all too easy to change the calling convention (which parameters are pushed in which order?) such that the DLL is only usable from C programs. Granted, the calling convention used by Windows is pretty well established as the standard for Windows systems, but the good doctor has seen DLLs fail because of mismatched calling conventions.
Writing a C-style interface for your DLL has some major limitations. First off, it restricts you from doing object-oriented programming because the object-oriented features of C++ require name decoration of function names. There is no standard for name decoration; in some cases, different versions of the same compiler decorate names differently. Second, implementing polymorphism is difficult. You can work around these problems by creating wrapper classes for both sides, but doing so is painful. And Dr. GUI's not into pain. (Not too much, anyway.)
Even if you did resolve the name decoration problems so you could link successfully to the DLL, other problems arise when it comes time to update your objects.
First off, you're hosed (that's a medical term) if you add any virtual functions to your object when you update it. You might think you're okay if you add the new functions to the end, but you're not: you've just shifted the vtable entries for all objects that inherit from you. And since a virtual function call needs a fixed offset into the vtable in order to call the correct function, you can't make any changes to the vtable?at least not without recompiling every program that uses your object or any object derived from it. Clearly, recompiling the world every time you update your object is not an option.
Second, if you're using new in your client to allocate objects, you won't be able to change the size of the object (that is, add any data) without recompiling the world.
Lastly (and most importantly), updating DLLs is a nightmare because you're stuck between a rock and a hard place with two unappetizing options: either try to update the DLL "in place" by overwriting it or rename the new version. Updating the DLL in place is very bad: the chances that even if you keep the interface consistent you'll break some user of your DLL are very high. Dr. GUI doesn't need to tell you of all the problems the industry, including Microsoft, has run into because of this issue.
The alternative?using a new DLL name?will at least keep your working systems working. But there's a cost in disk space (perhaps not a big deal when typical hard disks are 3 gigabytes or so), and a second cost: increased memory usage. If your user is using both versions of the DLL, there will be two copies of very similar code in the user's working set. It's not unusual when you examine a user's memory usage to find two or three versions of the Visual Basic runtime or the Microsoft Foundation Class (MFC) DLL, for instance. Given that almost all Windows systems typically use more virtual memory than they have physical memory, increasing the working set size has serious performance implications in the form of increased virtual memory swapping to disk. (That's why, to paraphrase a counter-example to Brook's law, adding more memory to a slow system makes it faster.)
Ideally, you'd like to allow your user (or application) to be able to choose what version to use. This is VERY hard with statically linked DLLs, but very easy if you dynamically load your DLL.
To be fair to C++, we should note that it was never intended to solve this set of problems. C++ was intended to allow you to reuse code in programs that reside in one file, so all of the objects are compiled at the same time. C++ was not intended to provide a way to build reusable binary components that can be mixed and matched over versions and years. By the way, the creators of Java noticed these problems?these deficiencies were a major motivation for developing Oak, which later became Java.
So what about Java?
Java does solve some of these problems, but it also adds some of its own. The biggest problem is that Java components (JavaBeans, usually) are only intended to be used by programs written in Java. Now it's true that the Microsoft virtual machine (VM) allows you to use JavaBeans as COM objects. You can therefore use them from any language. And it's true that Sun has a Java/ActiveX bridge. But in general, unless you're running on Windows, Java is a single-language system: Java components can only be used in Java programs. And, for the most part, you have to rewrite your systems from scratch to use Java. (Yes, you can make native calls?but it's a big hassle to do using Java Native Interface (JNI)?and your programs will no longer be at all portable.) Dr. GUI finds this pretty unacceptable, so he's glad that the Microsoft virtual machine (VM) is more flexible?for Windows, at least. No language, not even C++, Visual Basic, or Java, is right for every programmer and every problem.
Java also makes you decide when you write your program whether the component you're using is local (on your machine) or remote (on another machine)?and the methods for using local and remote components are quite different.
Java has a couple of other issues that make it a less-than-ideal answer for all component needs. First, it has no really solid way to deal with versioning. (The package manager in the Microsoft VM helps a lot with this issue.) Second, Java will be to one degree or another slower than C++. Dr. GUI notes that recent "it's as fast as C++" benchmarks published in an online Java magazine omitted tests where Java would do poorly. Two examples that come to mind are string and array manipulation (Java has to bounds-check each access), and initial method calls (Java has to look up the method by signature in a table in the class for the first call, although subsequent calls, which the magazine did test, can be fast). Finally, Java's "one-class-at-a-time" loading scheme can be considerably slower than loading all the code at once (even if there's less code!) because it requires so many more file or HTTP transactions, both of which have a high overhead.
Even if you're using Java in a way that gives good performance, your performance will suffer when you use Java components from another language because of the translation layer that needs to be there to link the dissimilar languages and object models.
Where Java shines is in the possibility that you can use your compiled components on dissimilar machines without needing to recompile for each machine's processor and operating system. But this often doesn't "just work"?you'll need to test and debug on every platform you intend to support.
So what's the alternative?
As it turns out, it is possible to use C++ to build DLLs and other binary components that are reusable. Both Dale Rogerson's book, Inside COM, and Don Box's book, Essential COM, start with a C++ class they want to reuse and solve each of the problems I've listed above (and a few more) with some slick tricks. And both of them end up with, not surprisingly, COM. In other words, each of the solutions to the problem of binary reuse is an important feature of COM. (If you'd like to check this progression out now, check out Markus Horstmann's article, From CPP to COM.)
While COM's "native language" is C++, it's relatively easy to use COM from C?the headers even support this. And, with a few language tweaks, it's possible to have two-way COM support from any language?Visual Basic, Java, Delphi, and so on. (By two-way COM support, I mean that it's possible both to use COM objects from that language, and to write COM objects in that language.) Implementing COM compatibility in your language run time isn't trivial, but the benefits are great: once you do, you open up a whole world of already written and debugged COM objects for your use. And there's a wide market for the COM components you write?the Giga Information Group estimates the current market at $400 million a year and expects it to be $3 billion in three years. (The COM-component market is growing faster than Microsoft!) Note that these market estimates are for third-party COM objects: they exclude COM components provided by Microsoft.
Another key feature of COM is that three types of objects are supported: in process (DLL), local (EXE in separate process on the same machine), and remote (DLL or EXE on a different machine via Distributed COM, or DCOM). You write code that uses COM components without worrying (or even knowing) what type of COM object you'll end up using, so you use the exact same code to hook up to an in-process, local, or remote object. How does COM hook you up to the right object? Well, it looks for the object's Class ID in the registry?and the registry entries tell COM which type or types of objects are available. COM does the rest, including starting processes and communicating over the network. (Note: there are performance differences between the different types of COM objects that you'll need to think about?but at least the code for connecting to and using the objects is exactly the same no matter what type of object you eventually use.)
COM doesn't solve all of the world's problems, however. For instance, it's still possible to break programs that use your component when you update a component. (Perhaps the fact that COM enforces a "black box" view of the component where it's not possible to find implementation details makes such breakage less common, but they still occur.) So you still have to choose between updating components in place and risking breakage, and using new Class IDs for new components. But COM does make it somewhat easier to write code that allows the user (or application) to choose what version it will use without recompilation.
Recall that COM components can be written in and used from most any language, and they can reside on any machine. That's nice. But what about cross-platform support?
Well, the cross-platform story is a good-news/bad-news story. The bad news is that there isn't very much COM on any platform besides Win32 right now. There are a couple of ports of COM to some non-Windows platforms, but not many. But that's not all the news.
The good news is that many more ports?to most common UNIX versions and to MVS?are coming, and soon. Further, Microsoft is doing some of the porting work itself. So it won't be long until COM and DCOM will be available on your favorite mainframes and UNIX boxes?availability for UNIX is scheduled to be announced in February. And think of how cool it'll be to have remote COM objects written in any language running on some fast mainframe that you can access from any language (Visual Basic, Java, Delphi, C++) on your machine. Check out the latest information on the Microsoft COM Web site (
http://www.microsoft.com/com/).
So if you're developing for Windows, you'll certainly want to consider writing COM objects, no matter whether you develop in Visual Basic, Java, C++, Delphi, or some other COM-compatible language. The objects you write will be usable on the local machine or remotely without rebuilding your component or the component's clients, thanks to the magic of COM and DCOM. And if you need your solutions to run on platforms other than Windows, COM is looking better and better, so it's still certainly worth looking into and seriously considering.
http://msdn.microsoft.com/library/defau ... 020298.asp