asp tutorials, asp.net tutorials, sample code, and Microsoft news from 15Seconds
Data Access  |   Troubleshooting  |   Security  |   Performance  |   ADSI  |   Upload  |   Email  |   Control Building  |   Component Building  |   Forms  |   XML  |   Web Services  |   ASP.NET  |   .NET Features  |   .NET 2.0  |   App Development  |   App Architecture  |   IIS  |   Wireless
 
Pioneering Active Server
 Power Search





Active News
15 Seconds Weekly Newsletter
• Complete Coverage
• Site Updates
• Upcoming Features

More Free Newsletters
Reference
News
Articles
Archive
Writers
Code Samples
Components
Tools
FAQ
Feedback
Books
Links
DL Archives
Community
Messageboard
List Servers
Mailing List
WebHosts
Consultants
Tech Jobs
15 Seconds
Home
Site Map
Press
Legal
Privacy Policy
internet.commerce














internet.com
IT
Developer
Internet News
Small Business
Personal Technology
International

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

HardwareCentral
Compare products, prices, and stores at Hardware Central!

COM Interop Exposed
By Patrick Steele
Rating: 4.5 out of 5
Rate this article


  • email this article to a colleague
  • suggest an article

    Table of Contents

    • Page 1
      • Introduction
      • A Brief History of COM and VB6
      • Multiple Interfaces
      • Almost to .NET!
      • Where Are My Methods?!

    • Page 2
      • Taking Control
      • Attributes
      • Controlling Your GUIDs

    • Page 3
      • Deployment
      • Local Deployment or the GAC?
      • Summary of Best Practices
      • Add Versioning
      • About the Author

    • download sample code

    Introduction

    Microsoft realized that the very first version of .NET needed a way to work with the existing Windows technology used to develop applications over the past 8+ years: COM. With that in mind, Microsoft added support in the .NET runtime for interoperating with COM - simply called "COM Interop". The support goes both ways: .NET code can call COM components and COM code can call .NET components.

    This article is geared towards VB6 programmers who are familiar with developing COM components and familiar with the concept of an interface. I'll review some background on COM, explain how VB6 interacts with COM, and then show how to design .NET components to smoothly interact with COM. In a future article, I'll discuss how to use an existing COM component in .NET applications.

    For those die-hard COM experts, there will be some things in this article that are oversimplified, but the concepts, as presented, are the important points to know for those developers supplementing their COM code with .NET components.

    A Brief History of COM and VB6

    One of the key concepts of COM is that everything is called through an interface. There is no such thing as simply creating a COM object and calling a method. You must use an interface.

    You're probably thinking "Wait a minute! I've coded hundreds of classes in VB6 and never needed an interface". That's right - you didn't need one because VB6 provided it for you in the background. Whenever you defined a public method on a class, VB6 made that method part of a COM interface and made your class implement the interface.

    For example, consider the following VB6 class from an ActiveX DLL project. The class is called "Robot":

    
    Option Strict
    
    Public Sub MoveForward()
    	...
    End Sub
    
    Public Sub FindCar()
    	...
    End Sub
    
    
    When you compile this into a DLL, VB6 creates an interface called "_Robot" (note the leading underscore) and a "coclass" called "Robot", which implements the interface "_Robot" (a "coclass" is the actual COM creatable object).

    The Microsoft utility OLE View is a tool used to examine the types defined in a COM component. OLE View should be installed under "Start, Programs, Microsoft Visual Studio 6.0, Microsoft Visual Studio 6.0 Tools, OLE View". Using the ActiveX DLL compiled above, I started up OLE View, selected "View TypeLib..." from the "File" menu and selected the DLL. Here are the important parts of the output:

    
        interface _Robot : IDispatch {
            ...
            HRESULT MoveForward();
            ...
            HRESULT FindCar();
        };
    
        coclass Robot {
            [default] interface _Robot;
        };
    
    
    The first item to point out is that there is an interface called "_Robot". This is the interface VB6 creates for us. It defines the two methods I added to the class (MoveForward and FindCar). Next, you'll see a "coclass" called "Robot". This represents the actual, creatable class. Since everything in COM is called through an interface, the "coclass" lists all interfaces supported by this object. Right now, there is only the "_Robot" interface - and it's marked with the "default" modifier.

    There are a lot of COM details about the default interface, but for this article, the importance of a default interface in terms of VB6 components is that of all the interfaces a class may implement, only the default interface supports late binding. And since scripting clients like VBScript only do late binding, the methods on the default interface are the only ones they can see.

    Multiple Interfaces

    COM will allow you to implement more than one interface. Take the ActiveX DLL from the previous section and add a new class module called "IMaid" (VB6 doesn't support directly creating a COM interface - more on that below). Here's the IMaid code:

    
    Option Explicit
    
    Public Sub CleanKitchen()
    	...
    End Sub
    
    Public Sub WashCar()
    	...
    End Sub
    
    
    Now add "Implements IMaid" to the Robot class:
    
    Option Explicit
    
    Implements IMaid
    
    Public Sub MoveForward()
    End Sub
    
    Public Sub FindCar()
    End Sub
    
    Private Sub IMaid_CleanKitchen()
    End Sub
    
    Private Sub IMaid_WashCar()
    End Sub
    
    
    If I compile this DLL now and examine it with OLE View, I see the following structures (again, only the relevant portions are shown below):
    
        interface _Robot : IDispatch {
            ...
            HRESULT MoveForward();
            ...
            HRESULT FindCar();
        };
    
        coclass Robot {
            [default] interface _Robot;
            interface _IMaid;
        };
    
        interface _IMaid : IDispatch {
            ..
            HRESULT CleanKitchen();
            ..
            HRESULT WashCar();
        };
    
        coclass IMaid {
            [default] interface _IMaid;
        };
    
    
    As noted earlier, VB6 does not support creating a true COM interface. However, since VB6 creates a COM interface with every class (prefixed with the underscore), the VB6 compiler will actually use the auto-generated interface when compiling the code when you use the "Implements" keyword on a class in VB6. So above, the Robot coclass implements the interface _Robot (automatically generated by VB6) and the _IMaid interface (the automatically generated one from the IMaid class).

    Also note that the _Robot interface created by VB6 is marked as the default interface. If you were going to use this object in a scripting environment (such as an ASP page), you could only access the MoveForward and FindCar methods. The methods implemented by the IMaid interface are not accessible since they are not on the default interface.

    Almost to .NET!

    If you've stuck around this long, the answer is yes, you're getting close to some .NET code! But it's important to know these concepts before you move into making .NET components that you expose to COM. Think of it as having a blueprint before starting to build a house. Sure, you can work without a blueprint, but the house will come out much nicer if you start off right.

    A quick recap of what happens in VB6 when it creates COM objects:

    • COM is interface based. Everything in COM must be called through an interface.
    • VB6 doesn't require that you implement a specific interface when creating a COM class. Instead, it will create an interface for you. Its name will be defined as your class name prefixed with the underscore (_) character.
    • The interface created by VB6 is always marked as the default COM interface and therefore only those methods are available to scripting clients (in the example above, VBScript can not access the IMaid methods of the Robot object).

    Where Are My Methods?!

    Many people who first expose a .NET object to COM notice that when they try and use the object in VB6, none of their methods are listed. Create a quick .NET class library that will be exposed to COM to see why that happens:

    [VB.NET]

    
    Option Strict On
    Option Explicit On 
    
    Namespace QuickNET
    	Public Class Bee
    		Public Sub FindFlowers()
    
    		End Sub
    
    		Public Sub MakeHoney()
    
    		End Sub
    	End Class
    End Namespace
    
    
    [C#]
    
    using System;
    
    namespace QuickNET
    {
    	public class Bee
    	{
    		public void FindFlowers()
    		{
    		}
    
    		public void MakeHoney()
    		{
    		}
    	}
    }
    
    
    Now create a COM type library from this .NET component to see what it looks like (this doesn't actually register it for COM - it just creates a COM type library). Go to a Visual Studio .NET Command Prompt (Start, Programs, Microsoft Visual Studio .NET, Visual Studio .NET Tools, Microsoft Visual Studio.NET Command Prompt), change to the directory of the above compiled .NET component and enter the following command:
    
    TLBEXP.EXE QuickNET.dll /out:Com.QuickNET.tlb
    
    
    The TLBEXP.EXE utility generates a COM type library from the .NET assembly. You can name the type library anything you want, but, by convention, it usually has a .tlb extension. I prefix my exported type libraries with "Com.". Now load up OLE View and open the type library "Com.QuickNET.tlb". Below are the relevant parts:
    
        coclass Bee {
            [default] interface _Bee;
            interface _Object;
        };
    
        interface _Bee : IDispatch {
        };
    
    
    This looks very similar to VB6 COM type libraries. You can see that an interface called "_Bee" was created for the "Bee" class and it's also the default interface. However, there are no methods on the interface. If you were to start up VB6 and add a reference to this tlb to your project, you'd notice by looking at the Object Browser that the Bee class has no methods (VB6 always looks at the "default" interface to see what methods are on the class).

    NOTE: The _Object interface isn't important for our discussion. Since everything inherits from the Object class in .NET and that class exposes a _Object interface, there's a _Object interface added to all exported types.

    So why didn't TLBEXP.EXE put all of the methods on the _Bee interface? Since the layout of a COM interface is a binding contract, adding new methods to a .NET class and then regenerating the COM type library might change that layout - thus breaking existing COM clients compiled against the old layout. By defining an empty interface, all clients will do late-bound calls and new versions of the .NET component (and its COM wrapper) will work without recompiling the COM clients.

    Taking Control >>

  • Rate This Article
    Not HelpfulMost Helpful
    1 2 3 4 5
    Other Articles
    Feb 23, 2005 - My Feature in Visual Basic 2005
    In this article, Thiru Thangarathinam demonstrates the different classes and features available through the My namespace. By providing a speed-dial that allows you to more quickly and effectively utilize .NET framework functionalities in your application, the My feature provides huge productivity improvements for .NET developers.
    [Read This Article]  [Top]
    Oct 6, 2004 - Creating Triggers Using Managed Code in SQL Server 2005
    Thiru Thangarathinam discusses taking advantage of the integation between the .NET CLR and SQL Server 2005 in order to do things like create triggers using managed code.
    [Read This Article]  [Top]
    Sep 8, 2004 - Custom Object Data Binding with .NET
    Developers often use brute force coding to marshal data between the GUI and application objects. In this article, Luther Stanton explains how to use .NET's out-of-the box data-binding functionality to make this job much easier.
    [Read This Article]  [Top]
    Aug 17, 2004 - The Perfect Service - Part 2
    Ambrose Little provides the complete source code for his 'Perfect Service' and explains how the .NET Service Manager enables features such as drag-n-drop deployment.
    [Read This Article]  [Top]
    Aug 12, 2004 - Middle-Tier Hosting: Enterprise Services, IIS, DCOM, Web Services, and Remoting
    There is broad-reaching debate about remoting, Web services, Enterprise Services, and DCOM. In short, it is a debate about the best technology to use when implementing client/server communication in .NET. Rocky Lhotka shares his thoughts on the issue while offering clear explanations of basic application architecture terminology.
    [Read This Article]  [Top]
    Jun 24, 2004 - The Perfect Service - Part 1
    The first article in this two-part series shows how to get Ambrose Little's .NET Service Manager running and then how to add plug-n-play services to it using drag-n-drop or XCOPY.
    [Read This Article]  [Top]
    May 25, 2004 - Generics In-Depth
    Although generics are extremely useful, they also seem to have a certain mystique that cannot be readily explained. This article hopes to remove that aura of mystery by showing just how easy it is to use generics and how useful they can be in many common situations.
    [Read This Article]  [Top]
    May 11, 2004 - SharePoint Security and .NET Impersonation
    When implementing custom components that require access to restricted resources, implicit impersonation must be used. Jay Nathan shows how to create a class that makes using .NET Impersonation a snap.
    [Read This Article]  [Top]
    Mar 23, 2004 - Exploiting .NET's Advanced Deployment Features
    Tony Arslan shows how to use VS .NET's custom deployment feature to create configuration files on the target machine during installation.
    [Read This Article]  [Top]
    Mar 18, 2004 - DevDays 2004 Round-Up
    Adnan Masood just returned from DevDays 2004 in Los Angeles. Here he provides some thoughts and insights into the Web application security-focused conference.
    [Read This Article]  [Top]
    Mailing List
    Want to receive email when the next article is published? Just Click Here to sign up.

    Support the Active Server Industry



    JupiterOnlineMedia

    internet.comearthweb.comDevx.commediabistro.comGraphics.com

    Search:

    Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

    Jupitermedia Corporate Info


    Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

    Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers