Interoperability Framework


Migrating an entire application to .NET may not be feasible. You can use existing COM components with new or migrated .NET applications .NET provides an interoperability framework to facilitate interoperability with COM components. Code in a COM component is unmanaged but code in a .NET application is managed.

.NET supports the following features for interoperability between managed and unmanaged code:

  • Object binding: Supports both early and late binding of components.

  • Data assembling and translation: Manages data type conversion among managed and unmanaged data types. For example, an integer type in VB 6.0 is of 16 bits but an integer type in VB.NET is of 32 bits.

  • Managing objects: Manages objects during their lifetimes and ensures that you release the objects or send them for garbage collection.

  • Object identity: Implements the identity rules of COM objects so that the COM components can be identified when you refer to the COM components from .NET applications.

  • Exception handling: Translates the values of COM HResult to .NET exceptions.

You can perform interoperability in two ways:

  • By calling unmanaged code from managed code

  • By exposing managed code to unmanaged code

Calling Unmanaged Code from Managed Code

You can call unmanaged code from managed code in three ways. The technologies that allow this interaction are:

  • Platform Invoke that allows you to call any function in any unmanaged language if its signature is redeclared in managed code.

  • COM interop using Runtime Callable Wrappers (RCW) allows you to call COM components in any managed language, such as VB.NET or C#, which behaves similar to normal managed components.

  • C++ interop allows the direct use of flat APIs and COM APIs. This powerful feature is specific to C++.

Platform Invoke Feature

You can call unmanaged code from managed code using the platform invoke feature. You can use the DLLImportAttribute class to identify the name of the DLL file and the function that you need to use. You need to declare the prototype of the function that you need to call from the unmanaged DLL in .NET code. When you call only a few unmanaged methods, it is better to use platform invoke. When you use a small part of unmanaged code and the remaining code is written in any other managed language, then the use of platform invoke will require an extra effort. For example, when you call the Win32 API functions that the Windows operating system exposes, you are performing platform invocation.

COM Interop Using RCW

You use COM interop to call methods of COM components in .NET applications because COM interop imports COM types to the .NET application. COM interop also assists forward compatibility to allow you to call managed .NET code from COM clients. COM interoperability is two ways. This means that .NET components can call COM components and vice-versa. When you talk about calling COM components from .NET clients, it is important to understand what are RCWs. All Win32 COM components are unmanaged code because the components were designed before CLR. CLR does not recognize unmanaged code. The managed components require that the other components with which they are interacting should be CLR-compliant. CLR places a wrapper called RCW around the COM component whose method you are calling in managed code. Figure 2-5 shows how RCW handles interoperability:

click to expand: this figure shows how rcw facilitates interoperability among com components and .net clients.
Figure 2-5: Run-Time Callable Wrappers

RCW changes COM metadata to .NET metadata. You use the type library importer (tlbimp) tool to perform this conversion. This tool is available in the .NET Framework Software Developer Kit. tlbimp tool reads metadata from a COM type library and creates a similar .NET interop assembly to call the COM component. The main functions of RCW are:

  • Managing interaction between the COM component and .NET

  • Creating and binding the COM object

  • Converting unmanaged COM interfaces to a managed form

  • Translating and assembling data among environments

  • Administering the wrapped COM object during its lifetime

In .NET client applications, you refer to COM components directly but actually, you use a RCW to fetch the objects in unmanaged code. To add a reference to a COM component to a VB.NET project:

  1. Select Project ->Add Reference from the menu bar.

  2. Select the COM tab in the Add Reference dialog box.

  3. Select the component from the list and click Select. If the desired component is not present in the list, select the Browse button to search the component. This adds the selected component to the Selected Components list. Click OK.

When you build the project, the runtime creates Interop.ComponentName.dll in the project's /BIN folder. The runtime derives the name of the DLL from the component’s name.

You can use the tlbimp method or the direct reference method to call the COM component but it is important to know when to call which method. The reasons for calling a particular method are:

  • To use a COM component that is to be shared with multiple projects, it is best to use tlbimp. Tlbimp allows you to sign the resultant assembly and store it in the Global Cache assembly, which allows you to create a RCW.

  • To create a COM component that is not to be shared with other projects, it is best to use direct reference.

  • To control the advanced details of the assembly, such as version number or namespace, you use tlbimp. You do not acquire control over advanced details if you use direct reference.

Note

To learn more about COM interoperability, see the COM Interop ReferencePoint.

C++ Interop

You can call unmanaged flat APIs from managed code through C++ interop used only in C++. You use C++ interop when you call COM components, depending on the Interface Definition Language (IDL) file that contains a number of interface definitions. C++ interop allows direct access to COM APIs. To call complex unmanaged APIs or simple unmanaged APIs that change while developing managed code, it is better to use C++ interop, which allows you to directly access unmanaged APIs.Figure 2-6 shows the flow diagram for calling unmanaged APIs:

click to expand: this figure shows the flow to call unmanaged apis. the unmanaged api type converts to com interop.
Figure 2-6: Flow Diagram for Calling Unmanaged APIs

Exposing Managed Code to Unmanaged Code

Using COM interop, you can expose the public managed class to unmanaged code. Although managed and COM object models are different, exposing a managed API as a COM API is easy because COM interop performs all the tasks. Managed code provides a few, new features that do not have corresponding features in COM code. COM clients can call exposed .NET code but COM clients do not have direct access to .NET code. To use a .NET component from a COM client, you create a proxy COM Callable Wrapper (CCW). COM components do not target the CLR and so cannot call managed code directly. You can solve this problem using a proxy. The proxy, which calls managed code from unmanaged code, is COM Callable Wrappers. Figure 2-7 shows how CCW handles interoperability while calling managed code from an unmanaged environment:

click to expand: this figure shows the ccw created when com clients call .net components.
Figure 2-7: COM Callable Wrapper Functionality

The two requirements that you need to meet before creating a .NET class that COM clients use are:

  • Defining an interface in .NET code and making the class implement the interface. When you implement the functionality through interfaces, the implementation provides key advantages to COM clients. Interfaces remain consistent with older versions while generating CCWs in .NET.

  • Declaring the classes as public that are noticeable to the COM clients. The tools through which you create CCW also define types based on public classes. The methods, properties, and events that COM clients use follow the same rules.

You can also sign .NET assemblies containing classes that COM clients can use with a cryptographic key pair. You sign the assembly with a strong name. .NET ensures that nobody tampers with the code in the assembly after you publish the assembly. All global assemblies, which are distributed among different clients, are required to follow this, though COM clients can call unsigned assemblies. You should ensure that you sign all the assemblies, including the private assemblies. This creates improved class IDs (CLSIDs) for managed classes and ensures that collisions do not occur between classes in different assemblies. The main functions of CCW are:

  • Managing interaction between COM and managed code

  • Creating and binding unmanaged code

  • Translating and assembling data among environments

  • Administering a .NET component during its lifetime

  • Translating the exceptions in .NET to COM HResult values




Migrating Unmanaged Applications to. NET
Migrating Unmanaged Applications to. NET
ISBN: N/A
EAN: N/A
Year: 2004
Pages: 31

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net