Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  Upgrading  »  .NET Interoperability - Calling COM Components from .NET
 »  Home  »  Windows Development  »  Interop  »  .NET Interoperability - Calling COM Components from .NET
.NET Interoperability - Calling COM Components from .NET
by Ashish Jaiman | Published  03/23/2002 | Upgrading Interop | Rating:
Ashish Jaiman

Ashish works as a Sr. Software Developer with Lexign Inc., an end-to-end trusted electronic transaction management software provider (http://www.lexign.com).

Ashish has 6 years of experience in designing and developing distributed systems, server technologies and web based software applications using Microsoft technologies, Java, XML and .NET. He holds MCSD (Microsoft Certified Software Developer) and SCJP (Sun Certified Java Programmer) certifications.

Contact Ashish at jaimanalwar@yahoo.com or ashish.jaiman@lexign.com.

 

View all articles by Ashish Jaiman...
.NET Interoperability - Calling COM Components from .NET

Article source code: interopdotnet.zip

.NET Framework exposes COM objects through a proxy called Runtime-Callable Wrapper (RCW). Primary function of RCW is to marshal call between a managed client (.NET) and unmanaged COM object. Runtime maintains single RCW for each COM object.

The aim of this article is to create a demo project to show how to call a COM component from .NET client and to implement events raised by the COM component. Example provided here uses COM server and .NET client extending functionality of the COM server using delegation.

Step 1

Let's start by creating the COM component (DotNETInterOp.dll) in VB. The component consists of a single class "CEmp", that have properties (FirstName, LastName, DOB) and raises event (Senior). After creating DotNETInterOp.dll register it by calling regsvr32 from command line

regsvr32 C:\testbeds\DotNETInterOP\DotNETInterOp.dll CEmp Class of the DotNETInterOp component
Option Explicit

Public Event Senior()
Private mstrFirstName As String
Private mstrLastName As String
Private mdtDOB As Date

Public Property Get FirstName() As String
  FirstName = mstrFirstName
End Property

Public Property Let FirstName(xstrFirstName As String)
  mstrFirstName = xstrFirstName
End Property

Public Property Get LastName() As String
  LastName = mstrLastName
End Property

Public Property Let LastName(xstrLastName As String)
  mstrLastName = xstrLastName
End Property

Public Property Get DOB() As Date
  DOB = mdtDOB
End Property

Public Property Let DOB(xdtDOB As Date)
  mdtDOB = xdtDOB
  If DateDiff("YYYY"mdtDOBNow> 60 Then
    RaiseEvent Senior
  End If
End Property
Generated using PrettyCode.Encoder

Step 2

To use the COM server we just created in .NET, Type Library of the component should be imported into Assembly containing metadata so that managed clients can create instances of the COM type and call its methods, just as if they were a .NET instance.

There are four ways to create an interop assembly

  • Add reference to the type library using Visual Studio.NET
    Open .NET project in Visual Studio.NET and add reference to the COM component using the Add Reference dialog box. This will automatically create interop assembly containing metadata.
  • Type Library Importer
    Use Type Library Importer (TlbImp.exe). TlbImp.exe is a command-line tool that converts COM type library to assembly containing metadata.
  • TypeLibConverter Class
    TypeLibConverter Class of the System.Runtime.InteropServices namespace provides methods to convert type library to assembly. This API can convert in-memory Type library and produces the same output as TlbImp.exe
  • Custom Wrappers
    You can create a duplicate definition of the class or interface in managed source code. You then compile the source code with compiler that targets the runtime to produce metadata in assembly. To define COM types manually, you must know exact descriptions of the coclasses and interfaces being defined and know the type library-to-assembly conversion rules. Writing custom wrapper is advanced technique that you seldom perform.

In our example we will use the TlbImp.exe to create metadata from the coclasses and interfaces definitions in our DotNETInterOp.dll Type library. From the command line run

tlbimp C:\testbeds\DotNetInterOP\DotNETInterOp.dll
/out:C:\.NET\TestBeds\VB\RCW\RCW\DotNETInterOp.dll

Step 3

Use the COM server, as it was a .NET component, add reference to the assembly created in the previous step and code against the assembly by creating CEmp object and delegation the calls to this object.

The .NET Client has two classes CEmp and CEmps, CEmp is a wrapper over our COM component's CEmp and exposes FirstName, LastName and IsSenior properties. The FirstName, LastName properties just delegate to the properties of COM's CEmp but IsSenior uses the event raised by the COM component to set its value. The CEmps class is a collection of CEmps and exposes methods to test our code.

VB.NET Client for the COM Component
Imports System.Collections
Public Class CEmps
    Private Emps As ArrayList
    Sub New()
        Emps = New ArrayList()
        Dim objEmp As CEmp
        objEmp = New CEmp("John""Doe""01/01/1970")
        Emps.Add(objEmp)
        objEmp = New CEmp("Mike""Edwards""01/01/1941")
        Emps.Add(objEmp)
        objEmp = New CEmp("Debra""Bunn""01/01/1930")
        Emps.Add(objEmp)
    End Sub
    Public Function Print() As String
        Return Print(True& Print(False)
    End Function
    Public Function Print(ByVal xblnSeniors As BooleanAs String
        Dim intCount As Integer
        Dim objEmp As CEmp
        Dim strPrint As String
        For intCount = 0 To Emps.Count - 1
            objEmp = CType(Emps(intCount), CEmp)
            If xblnSeniors = objEmp.IsSenior Then
                strPrint = strPrint & Print(objEmp& Chr(13)
            End If
        Next
        Return strPrint
    End Function
    Private Function Print(ByVal xobjEmp As CEmpAs String
        Dim strPrint As String
        strPrint = xobjEmp.FirstName & Chr(9& xobjEmp.LastName
        Return strPrint
    End Function
End Class

Imports System
Imports Microsoft.VisualBasic
Imports DotNETInterOp
Public Class CEmp
    Private mobjEmp As DotNETInterOP.CEmp
    Private mblnIsSenior As Boolean
    Sub New(ByVal xstrFName As String_
        ByVal xstrLName As StringByVal xdtDOB As Date)
        mobjEmp = New DotNETInterOp.CEmp()
        AddHandler mobjEmp.Senior_
            New DotNETInterOp.__CEmp_SeniorEventHandler_
            AddressOf Senior)
        With mobjEmp
            .FirstName = xstrFName
            .LastName = xstrLName
            .DOB = xdtDOB
        End With
    End Sub
    Public ReadOnly Property FirstName()
        Get
            Return mobjEmp.FirstName
        End Get
    End Property
    Public ReadOnly Property LastName()
        Get
            Return mobjEmp.LastName
        End Get
    End Property
    Public ReadOnly Property IsSenior()
        Get
            IsSenior = mblnIsSenior
        End Get
    End Property
    Private Sub Senior()
        mblnIsSenior = True
    End Sub
End Class
Generated using PrettyCode.Encoder

Related Articles

.NET Interoperability - Calling a .NET Component from a COM Component

How would you rate the quality of this article?
1 2 3 4 5
Poor Excellent
Tell us why you rated this way (optional):

Article Rating
The average rating is: No-one else has rated this article yet.

Article rating:2.89285714285715 out of 5
 28 people have rated this page
Article Score17658
Sponsored Links