COM differs from the .NET Framework object model in many different ways. To make it easier for managed and unmanaged code to coexist, the CLR provides two wrapper classes that hide the differences between the two, allowing both managed and unmanaged clients to call each other’s objects. Whenever your managed client calls a method on a COM object, the runtime creates a Runtime Callable Wrapper (RCW). When a COM client references a .NET object method, the runtime creates a Callable COM Wrapper (CCW).
The RCW and CCW wrappers act as a proxy between unmanaged COM code and managed .NET code. The wrappers marshal method arguments and return method values whenever the client and server have different representations of the data being passed between them.
A CCW is an unmanaged COM object. It is not garbage collected and is destroyed when the last client reference is released. After a CCW is destroyed, the managed object it wraps is also marked for garbage collection. Some of the tasks that a CCW is responsible for when a COM component references a managed .NET component include
- Managing the lifetime of the .NET component
- Creating and binding to the managed object
- Converting .NET exceptions to COM HRESULT values
- Synthesizing multiple COM interfaces (IUnknown, IDispatch, etc.) based on object type information
- Marshaling and data translation between environments
RCW is a managed object and therefore the CLR collects garbage. Some of its responsibilities include
- Managing the lifetime of a packaged COM object
- Creating and binding to the main COM object
- Broadcasting and marshaling data between environments
- Using COM interfaces and factorizing interfaces into a manageable form
- Convert COM HRESULT values to .NET exceptions
To reference a method in a managed class from a COM client, you must first create a COM type library for the managed object and then register it. There are several ways you can accomplish this in .NET. You can run the type library export command line utility tlbexp.exe to create a COM type library. However, this will only create the type library; it will not register it. You can also run the regasm.exe command-line utility. This utility creates the type library and automatically registers it for you. Finally, you can configure Visual Studio .NET to do both tasks automatically at creation time by setting attributes on the managed class’s properties page.