Introduction to the interoperation between .Net and COM: Part I
This is a brief introduction to the COM component object model.
What is COM ?
COM stands for component object model. It is an application interface introduced by Microsoft in 1993 in order to enable intercommunication between different and heterogeneous processes, and I mean by heterogeneous processes those created within different environments and I suppose that every one among the VB6.0 and/or VC++6.0 programmers including me knew a lot about COM. OLE and ActiveX sound something in the ear of a VB6.0 and/or VC++6.0 programmer, I'm sure. Before the .Net technology, there are not common language runtime that provides interoperation between different components those created with different .Net languages. Moreover, there is not .Net remoting that enables communication between different components within a remoting context. The COM and the DCOM that stands for distributed component object model do the job instead. In deed COM/COM+ and DCOM aren't the only ones in the nature, there is also CORBA and RMI too, witches essentially used within the JAVA platforms.
Why the COM paradigm still exists?
The raison is very simple; there are tons of lines of codes and innumerable components written with unmanaged code those could be very interesting and useful within a .Net application context. So Microsoft found itself in a situation of choosing between three strategies, the first one is to translate permanently all the unmanaged codes to managed ones, the second strategy consists on using only managed code and ignoring all code written outside the .Net context, I mean using languages and environments other than adopted by the .Net context such as Visual studio 6.0 or CODE::BLOCS and the third strategy consists on creating an API that enables intercommunication between the inside and the outside of the .Net environment.
Concerning the first strategy, it is good to translate all code to the managed one because it provides two convenient things, first, it provides the homogeneity since all the code belongs to the same environment, and second, it minimizes the security risks because none homogeneous code versions could increase the likelihood of errors and exceptions, something that could be a very precious gift for the attackers. But translating unmanaged code to the managed one is not a good alternative. It costs a lot in terms of time and endeavor since COM components are numerous and there are many talented programmers whose still develop components outside the .Net environment using VC++6.0 and VB6.0 for example, therefore this strategy is discarded by Microsoft.
Concerning the second strategy, it is worth to build a bridge between the external environment and the .Net one rather than isolate this last one. In fact, there is a social theory pronounced by a Tunisian scientist and the sociology founder that could be applied to this context. "Made that the human is civilized, he depends on the other humans, other than him, if not he cannot survive" IBN KHALDOUN. According to this theory, the human couldn't survive solely without interacting with its external world; same think could be said according to the .Net technology that couldn't survive if there aren't interactions with its external environments, hence this second strategy is also rejected.
Finally, the last strategy constitutes the solution, because writing a standard API that enables interaction with unmanaged code gives the .Net environment the possibility to be extended or enriched by new functionalities that may not already exist within it. Moreover, there is one standard and conventional API used to interact with any external or unmanaged code. Hence COM Interop came to live.
How to profit of the COM services from within .Net environment ?
First, the .Net could use and provides interaction with COM objects easily from within Visual studio. To integrate a COM object within your .Net application your can simply add a reference to it in a condition that this first one is already registered. We will come back in more details to this point; I mean the component registration in the next section. To integrate a registered COM component, you just follow those steps. First, go to the solution explorer and right click on the project then press add a reference.
When the bellow window appears, select the COM tab and then a large list appears. This list contains entire panoply of registered COM component those could directly be used within your code.
In fact, unlike the .Net component, the COM ones should be registered before being used within a .Net application, the Windows system provides a tool for that, it is the RegSvr32.exe that is found in C:\WINDOWS\System32, it has as mission to register the COM assemblies those not already have been registered within the registry entry but the assemblies represented as dll or exe must be strongly named before, the regsvcs.exe is also a convenient tool to leverage the same task by the way. Unfortunately, this operation couldn't be done within other operating systems that support .Net such as LINUX or SOLARIS, I mean using Mono framework, because only windows system holds a registry entry module.
Do the COM components interact directly with the .Net equivalent ?
Not exactly, in fact when a COM assembly is requested to be consumed within a given .Net client, the .Net framework creates a proxy object named Runtime Callable Wrapper RCW. As its name indicates, it is a wrapper that could be used as a clove to enable the COM object to be accessed and used by the managed code. It is out of the scope of the developer hands. Of Corse, it is invisible to this last one, and the entire operation is done in the runtime behind the hood. The Runtime Callable Wrapper marshals call between the two sides. The COM component is allowed to use one and only one Runtime Callable Wrapper, even if several references are passed to different .Net clients.
In the other direction, If we are performing some code outside the .Net context, say that we use VC++6.0 to develop a C++ application client that needs services provided by a given .Net assembly. A proxy will be generated to enables communication between the two sides but it is a different one, it is called a component callable wrapper a CCW. The common language runtime also creates only one proxy for the .Net component regardless of the COM applications number, I mean the application those make use of the .Net component. Its existence is depending on the references number to the .Net component, if the number attempts 0 then the CCW is garbage collected.
In the .Net context, objects using the other technology appear as native objects.
What should one know before start developing COM component ?
There are some rules that has to be respected when developing or/and using a COM component in order to interact with the equivalent in .Net side.
How to generate a COM from .Net and How to generate a .Net from COM?
- First, COM types doesn't allow parameterized constructor within its objects or classes for the simple raison that languages such as VB6.0 and previous versions, for example, doesn't support parameterized constructors.
- Other issue that could be seen as a drawback within the COM is that it doesn't support inheritance something that discards the possibility of reusing and extending the COM object if this action is needed.
- Moreover, all COM types and members must be public something that violates in some kinds other one of the principles of the oriented object paradigm, namely the encapsulation.
- The abstract classes aren't supported either.
- And finally, operating system such as LINUX doesn't have a registry system something that reduces the portability of .Net across the other platforms.
However this section will be the main subject of the two following part, I mean Part II, III, I will give a general idea about the mechanism:
- If you want to generate a .Net component from the COM one, you may use tlbimp.exe that stands for type library importer, it converts the type definitions found within a COM type library into equivalent definition in managed Metadata format. But before, you may register your assembly using regsvr32.exe in the registry entry.
- If you want to export your .Net product in order to be used within an unmanaged code environment you may do register it using regasm.exe and use tlbexp.exe that stands for type library exporter, it does exactly the opposite process of the previous one and I mean tlbimp.exe. Either you may use the regsvcs.exe if your .Net assembly is within a trusted zone, otherwise you must sign it in order to be strong named one. This tool represents an advantage is that it performs all tasks at once.
- Loads and registers an assembly.
- Generates, registers, and installs a type library into a specified COM+ 1.0 application.
- Configures services that you have added programmatically to your class.
Is it possible to use a simple stand alone ActiveX object (*.ocx) in .Net application ?
Yes it is possible to only use a simple ActiveX control instead of an entire COM application, for that, the .Net framework provides the tool aximp.exe.
Then why should I use the COM ?
It is simply because COM is still used as a windows feature in XP and even in VISTA version. As long as Microsoft is still using COM and not completely moved to the dot Net technology. The COM continues to exist with same the importance as the EJB in the Java side.
Where could one localize the COM applications?
All the COM serviced components are located in Start>Configuration panel>Administration tool>Components services.
How the operating system deals with COM components ?
Currently, COM components are mainly and exclusively used under Windows. It's quite simple, all the serviced components are gathered and wrapped in a container called COM+ that is the enterprise version of the COM, and in my point of view COM+ is nothing other than COM, as the windows is not totally a .Net built in operating system. As the COM components are basically server side ones, they are loaded by the operating system when are requested, the DCOM or the .Net remoting techniques are used to marshal requests between the client side and the server side if we are in a remoting context. Generally, client applications could access COM services via either instantiation or activation where an assembly named dllhost.exe is triggered to host the targeted server side assembly in the memory.
In the next article, we will see how to build a COM application from within Visual Studio.