As Ive suggested, the many system services and components that use COM will need to be supported for the foreseeable future, so development of COM-based applications will continue during the gradual movement to a .NET-based world.
Technologies provided by Microsoft in the .NET Framework and Visual Studio .NET under the general heading of COM interop enable the integration of .NET and COM code in both directions. This will make it possible to move gradually from COM-based applications, which use ActiveX controls and other COM components, toward full .NET applications that use .NET controls.
The .NET Framework provides two types of interoperability. The first is used by the Platform Invoke (or P/Invoke) mechanism to call unmanaged functions in Win32 DLLs. The second is COM interop, which is used to interact with unmanaged COM code. Much of the basic functionality is common to both types of interoperability, but COM interop adds another layer of COM compatibility.
COM components cannot be used directly in .NET code. Instead, tools either within Visual Studio .NET or stand-aloneare used to produce .NET wrapper classes that can be used like any other .NET class. These wrappers are called Runtime Callable Wrappers (or RCWs), and they implement all the lifetime management and interface functionality needed to let COM components interact with .NET code, as well as implementing COM interfaces as .NET interfaces.
For example, the RCW code maintains a reference count on the COM object, and when the garbage collector collects the RCW because there are no references to it from .NET clients, the RCW will release the interface pointers being held to the COM object. Note that there is always one RCW per COM object, regardless of the number of clients that might hold references to that object. Figure 1-1 shows how the RCW bridges between managed and unmanaged code, acting as a proxy to the COM object and exposing its interfaces to .NET clients .
RCWs are used to wrap COM components, and can also be used to wrap ActiveX controls so that they can be used in the Visual Studio .NET designers. In the majority of cases, RCWs provide transparent access to COM components for the .NET programmer. RCWs are discussed in more detail in Chapter 3.
Although it is less common, you can use .NET components as COM objects. You might want to do this with an ongoing COM-based project if you decide that developing components is much easier using .NET and C# rather than C++ and ATL. Once again, tools enable the creation of a wrapperthis time a COM Callable Wrapper (CCW)which makes a.NET object look and behave like a COM component. There is one CCW per .NET object, no matter how many COM clients are using it.
The CCW has to provide COM interfaces that make the .NET component look like a COM component. This means it has to implement IUnknown , and might well implement other standard interfaces, such as IDispatch or ISupportErrorInfo . The .NET component might not expose functionality via interfaces, in which case the CCW will need to fabricate COM interfaces through which to expose the public members of the component class. Figure 1-2 shows a representation of a CCW.
The CCW must also ensure the .NET object stays alive as long as any COM client holds an interface pointer, and since COM client code in C++ deals with raw interface pointers, the CCW must ensure all addresses remain valid if the garbage collector decides to move .NET objects around in memory.
CCWs are discussed in more detail in Chapter 4.
Although RCWs let you use ActiveX controls in Windows Forms applications, there is no built-in mechanism currently supplied to let you use a .NET Windows Forms control as an ActiveX control except on Web pages displayed in Internet Explorer.