Lesson 3: Interoperating with COM

Lesson 3: Interoperating with COM

COM objects are another type of unmanaged code that you can use from .NET assemblies. Because COM is widely used, Visual Studio includes built-in tools for importing and using COM objects within .NET assemblies. Visual Studio also includes the option of automatically registering .NET class library assemblies for use from COM.

In this lesson, you ll learn both sides of the equation: how to use COM objects from .NET, and how to create .NET objects for use from COM. Together, these techniques allow you to integrate ASP.NET Web applications into existing software architecture.

After this lesson, you will be able to

  • Create references to COM objects and use them from .NET code

  • Register .NET class libraries for use from COM

  • Selectively hide or expose public members of a .NET assembly for use with COM

  • Handle exceptions that occur between .NET and COM objects

  • Understand the limitations of using .NET objects from COM and of using COM objects from .NET

Estimated lesson time: 20 minutes

Using COM Objects from .NET

To use a COM object from a .NET assembly in Visual Studio, follow these steps:

  1. Install and register the COM object on your system.

  2. Open the .NET project in Visual Studio, and add a reference to the COM object, as shown in Figure 7-3. If the COM object does not appear on the COM tab of the Add Reference dialog box, you can add a reference directly to the executable by clicking Browse.

    figure 7-3 adding a reference to a com object

    Figure 7-3. Adding a reference to a COM object

  3. Create an instance of the COM object in code, and use it as you would any other object.

When you add a reference to a COM object, Visual Studio automatically generates an interop assembly for the object and places it in the project s /bin folder. The interop assembly is created from the COM object s type information and contains the metadata that the CLR uses to call the unmanaged code in the COM object.

You can view this interop assembly using the Microsoft Intermediate Language Disassembler (Ildasm.exe) included in the .NET Framework. Figure 7-4 shows the interop assembly generated for a simple COM object named ShapesCOM.

figure 7-4 viewing the interop assembly

Figure 7-4. Viewing the interop assembly

You use COM objects from within .NET code the same way that you use .NET classes. For example, the following code creates instances of the Circle and Sphere COM objects and uses some of their members:

Visual Basic .NET

Private Sub butCalc_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles butCalc.Click ' Create a Circle COM object. Dim Circle As New ShapesCOM.Circle ' Set the property. Circle.Radius = CSng(txtRadius.Text) ' Call the method. lblArea.Text = Circle.Area.ToString() ' Create a Sphere COM object. Dim Sphere As New ShapesCOM.Sphere ' Set the property. Sphere.Radius = CSng(txtRadius.Text) ' Call method. lblVolume.Text = Sphere.Volume.ToString() End Sub

Visual C#

private void butCalc_Click(object sender, System.EventArgs e) { // Create a Circle COM object. ShapesCOM.Circle Circle = new ShapesCOM.Circle(); // Set the property. float fRadius = System.Convert.ToSingle(txtRadius.Text); Circle.Radius = fRadius; // Call the method. lblArea.Text = Circle.Area().ToString(); // Create a Sphere COM object. ShapesCOM.Sphere Sphere = new ShapesCOM.Sphere(); // Set the property. Sphere.Radius = fRadius; // Call the method. lblVolume.Text = Sphere.Volume().ToString(); }

NOTE
Visual Basic 6.0 allowed you to create COM properties (Property Let procedures) that were assigned by reference. Visual C# won t recognize those properties. To use COM properties from Visual C#, they must be assigned by value.

Building .NET Objects for Use from COM

Visual Studio can automatically generate type library information and register a .NET class library assembly for use from COM. These automatic tools do not work for ASP.NET Web applications, so you must isolate the code you want to use from COM in its own Class Library project.

To create .NET objects for use with COM, follow these steps:

  1. Create a .NET class library project containing the objects you want to use from COM.

  2. In the project s Build options, select the Register For COM Interop check box, as shown in Figures 7-5 and 7-6.

    figure 7-5 registering a visual basic .net project for com interop

    Figure 7-5. Registering a Visual Basic .NET project for COM interop

    figure 7-6 registering a visual c# project for com interop

    Figure 7-6. Registering a Visual C# project for COM interop

  3. Build the project.

When you register a project for COM interop, Visual Studio automatically creates a type library for the public classes and members in the .NET assembly and registers those classes with the system registry.

Hiding Public .NET Classes from COM

In some cases, you might want to hide selected .NET classes from COM but keep them public for use from other .NET assemblies. The ComVisible attribute allows you to select which public .NET classes and members are included in the generated type library. This attribute applies hierarchically for the assembly, class, and member levels. For example, the following code hides all public classes in the assembly, exposes the Circle and Sphere classes, and hides the Sphere class s Center method:

Visual Basic .NET

' From AssemblyInfo.vb ' Hide public members from COM by default. <Assembly: ComVisible(False)> ' From Shapes.vb Imports System.Runtime.InteropServices ' Interface for all shapes. Public Interface IFigure Property Top() As Single Property Left() As Single Function Area() As Single Function Perimeter() As Single End Interface ' Definition of abstract class. <ComVisible(True)> Public MustInherit Class Shape Implements IFigure Public MustOverride Property Top() As Single Implements IFigure.Top Public MustOverride Property Left() As Single Implements IFigure.Left Public MustOverride Function Area() As Single Implements IFigure.Area Public MustOverride Function Perimeter() As Single Implements IFigure.Perimeter End Class <ComVisible(True)> Public Class Circle Inherits Shape Private sxCenter, syCenter As Single Private sRadius As Single Public Overrides Property Top() As Single Get Top = sxCenter - sRadius End Get Set(ByVal Value As Single) sxCenter = Value + sRadius End Set End Property Public Overrides Property Left() As Single Get Left = syCenter - sRadius End Get Set(ByVal Value As Single) syCenter = Value + sRadius End Set End Property Public Overrides Function Area() As Single Area = 2 * System.Math.PI * (sRadius ^ 2) End Function Public Overrides Function Perimeter() As Single Perimeter = 2 * sRadius * System.Math.PI End Function Public Property Radius() As Single Get Radius = sRadius End Get Set(ByVal Value As Single) sRadius = Value End Set End Property Public Overridable Sub Center(ByVal X As Single, ByVal Y As Single) sxCenter = X syCenter = Y End Sub End Class <ComVisible(True)> Public Class Sphere Inherits Circle Private sCenter As Single Public Overrides Function Area() As Single Area = 4 * System.Math.PI * (MyBase.Radius ^ 2) End Function <ComVisible(False)> Public Shadows Sub Center(ByVal X As Single, _ ByVal Y As Single, ByVal Z As Single) MyBase.Center(X, Y) sCenter = Z End Sub Public Function Volume() As Single Volume = (4 / 3) * System.Math.PI * (Radius ^ 3) End Function Public Property Front() As Single Get Return sCenter - Radius End Get Set(ByVal Value As Single) sCenter = Value + MyBase.Radius End Set End Property End Class

Visual C#

// From AssemblyInfo.cs // Hide public members from COM by default. [assembly: ComVisible(false)] // From Shapes.cs [ComVisible(true)]public class Sphere : Circle { float fCenter; // Constructor. public Sphere() { // Initialize internal variable. fCenter = 0; } public override float Area() { return (float)(4 * Math.PI * Math.Pow((double)base.Radius, 2)); } [ComVisible(false)]public new void Center(float X, float Y) { this.Center(X, Y, 0); } [ComVisible(false)]public void Center(float X, float Y, float Z) { base.Center(X, Y); fCenter = Z; } public float Volume() { return (float)((4 / 3) * System.Math.PI * Math.Pow((double)base.Radius, 3)); } public float Depth { get { return fCenter - base.Radius; } set { fCenter = value + base.Radius; } } } [ComVisible(true)] public class Circle : Shape { float fxCenter, fyCenter, fRadius; // Constructor. public Circle() { // Initialize internal variables. fxCenter = 0; fyCenter = 0; fRadius = 0; } public override float Top { get { return fxCenter - fRadius; } set { fxCenter = value + fRadius; } } public override float Left { get { return fyCenter - fRadius; } set { fyCenter = value + fRadius; } } public override float Area() { return (float)(2 * System.Math.PI * Math.Pow((double)fRadius, 2)); } public override float Perimeter() { return 2 * fRadius * (float)System.Math.PI; } public float Radius { get { return fRadius; } set { fRadius = value; } } public virtual void Center(float X, float Y) { fxCenter = X; fyCenter = Y; } } [ComVisible(true)] public abstract class Shape : IFigure { // Constructor. public Shape() { } public abstract float Top { get; set; } public abstract float Left { get; set; } public abstract float Area(); public abstract float Perimeter(); } public interface IFigure { float Top { get; set; } float Left { get; set; } float Area(); float Perimeter(); }

Notice that the Shape abstract class in the preceding code is visible to COM. Although Shape is not a creatable class and thus can t be used from COM, it must be visible to enable the use of its derived classes (Circle and Sphere) from COM.

Tools Used by COM Interop

Visual Studio automatically generates the interop assembly, type libraries, and other information for .NET to COM interoperation. Alternatively, you can use the command-line tools included with the .NET Framework and described in Table 7-1.

Table 7-1. COM Interop Tools

Tool

File name

Use to

Type Library Importer

Tlbimp.exe

Generate a .NET interop assembly for a COM object

Type Library Exporter

Tlbexp.exe

Generate a COM type library from a .NET assembly

Intermediate Language Disassembler

Ildasm.exe

View the generated interop assembly or other .NET assemblies

Assembly Registration Tool

Regasm.exe

Add or remove system registration database entries for a .NET assembly

Registry Editor

Regedit.exe

View system registry database entries for COM objects installed on a system, including .NET objects registered for COM interop

Handling Exceptions Between .NET and COM

.NET handles errors through exception classes. COM handles errors through 32-bit data types called HRESULTs. All of the .NET exception classes include HResult properties that map to COM HRESULT codes.

If an exception occurs in a .NET object, the exception is automatically mapped to the appropriate HRESULT and returned to COM. Similarly, if an exception occurs in a COM object, the COM HRESULT is mapped to the appropriate exception class, which is returned to .NET, where it can be handled just like any other exception.

If you are creating your own .NET exception classes for use with COM, be sure to set the class s HResult property so that the exception can be handled within COM.

Limitations of COM Interop

The .NET Framework was developed to address the limitations of COM. Because of this evolution, there are limits to the .NET features that you can use from COM. The following list describes these limits:

  • Shared/static members

    COM requires objects to be created before use, so it does not support .NET Shared/static members.

  • Shadows/new members

    COM flattens the inheritance tree of .NET objects, so members in a derived class that shadow members inherited from a base class are not callable.

  • Constructors with parameters

    COM can t pass parameters to an object s constructor.

In addition to these technical limitations, you should also be aware of these practical limitations when using COM objects from .NET:

  • Shared solutions might not allow COM objects.

    ASP.NET host service providers that use nondedicated servers can limit or prohibit the installation of COM objects on their servers.

  • COM objects are prone to memory leaks.

    COM uses reference counting to determine when to destroy objects and free memory. It is possible for this reference count to become incorrect, leaving objects in memory indefinitely.

  • Type libraries might be inaccurate.

    Because COM separates the object s description from its implementation, it s possible for this description to not accurately reflect the object. In this case, the generated interop assembly will also include those inaccuracies.

  • COM is unmanaged code.

    The limitations cited for unmanaged procedures in Lesson 2 apply to COM objects as well.



MCAD(s)MCSD Self-Paced Training Kit(c) Developing Web Applications With Microsoft Visual Basic. Net and Microsoft V[.  .. ]0-315
MCAD(s)MCSD Self-Paced Training Kit(c) Developing Web Applications With Microsoft Visual Basic. Net and Microsoft V[. .. ]0-315
ISBN: N/A
EAN: N/A
Year: 2003
Pages: 118

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