CodeGuru
Earthweb Search
Forums Wireless Jars Gamelan Developer.com
CodeGuru Navigation
Member Sign In
User ID:
Password:
Remember Me:
Forgot Password?
Not a member?
Click here for more information and to register.

Become a Marketplace Partner

jobs.internet.com

internet.commerce
Partners & Affiliates
















RSS Feeds

RSSAll

RSSVC++/C++

RSS.NET/C#

RSSVB

See more EarthWeb Network feeds

Home >> .NET / C# >> C# >> Miscellaneous >> COM


Writing Your Own COM Interop in C#
How to interface with COM objects that use IUnknown-derived interfaces.
Rating:

darwen (view profile)
January 24, 2005

Environment:  C#, C++, DevStudio 2003

Go to page: 1  2  Next

Introduction

Although the automatic creation of COM interop DLLs is very useful, it is not perfect.


(continued)



In the case of interfacing with OLE conforming COM objects (for example, interfaces derived from IDispatch and method parameters that are part of the VARIANT structure), the interop DLL automatically created by VisualStudio (or rather by TlbImp.exe, the application that generates the interop DLL) is more often than not sufficient.

However, this method does have its drawbacks. First, it requires the creation of an additional DLL for each COM DLL.

Second, if you need to use IUnknown-based interfaces that may not even be defined in the type library, no automatic interop DLL can be created.

Third, the marshalling of method parameters in such cases is often incorrect, rendering the automatic interop DLL useless.

And finally, there's no way to group the objects into seperate namespaces—meaning the interop DLL for a COM DLL containing many objects tends to create a huge jumble of classes with no clear ordering. One way around this problem is to write a wrapper in C++.NET, but this still requires an additional interfacing DLL to exist in between the C# client and the COM DLL.

In this article, I will explore how to use P/Invoke, and the COM interop classes to gain access to COM objects and present a class structure to ease the process. I will concentrate on COM inproc-servers in this article, but the methods described here can be applied to any type of server—even DCOM-based servers.

Instansiating a COM Object

How do you instansiate a COM object? In actual fact, the same way that you do in C++—by using the CoCreateInstance method. This is defined in ole32.dll.

For information about the CoCreateInstance method, see the following Web site:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/cmf_a2c_1nad.asp.

The interop declaration is as follows:

public class Ole32Methods
{
   [DllImport("ole32.Dll")]
   static public extern uint CoCreateInstance(ref Guid clsid,
      [MarshalAs(UnmanagedType.IUnknown)] object inner,
      uint context,
      ref Guid uuid,
      [MarshalAs(UnmanagedType.IUnknown)] out object rReturnedComObject);
}

A point to note is the [MarshalAs(UnmanagedType.IUnknown)] attributes. These inform the P/Invoke mechanism that the objects are in fact IUnknown interfaces and should be treated as such. The result of these attributes is to wrap up the 'object' parameters in an internal .NET class that handles the IUnknown methods of AddRef, QueryInterface, and Release (__ComObject). Therefore, because P/Invoke knows that the return object is in fact an IUnknown, its Release method will be called when the object is finalized.

If the COM object doesn't exist, or there was an error in the creation of the COM object, the rReturnedComObject parameter will be set to null and an error code (for example, a value not equal to zero) will be returned from the function. The Guid struct is already defined in .NET, and is synonymous with the GUID struct in C++.

Finally, I've labelled rReturnedComObject as 'out' and not 'ref'. This indicates that the object returned is created inside of the method. An example of the code to instansiate a COM object using this method is shown below.

static bool CreateObjectExample()
{
   const uint CLSCTX_INPROC_SERVER = 1;

   // CLSID of the COM object
   Guid clsid = new Guid("F333F56A-B59D-41FE-822D-27989266A535");

   // GUID of the required interface
   Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");

   object instance = null;

   uint hResult = Ole32Methods.CoCreateInstance(ref clsid, null,
                  CLSCTX_INPROC_SERVER, ref IID_IUnknown, out instance);

   return hResult == 0;
}

Unfortunately, the object that is returned isn't much use at present. It effectively represents an instance of the COM object without any interfaces, or at least with just an IUnknown interface to which you don't have access.

Defining Interfaces

You need to manually define each interface on the COM object. These can be derived from the .idl of the COM DLL in question. In defining the methods of the interfaces, standard P/Invoke marshalling applies. Consider the following method definition as it would appear in a .idl file.

[
   object,
   uuid(F333F56A-B59D-41FE-822D-27989266A535),
        pointer_default(unique)
]
interface ITestInterface1 : IUnknown
{
   HRESULT GetString(LPSTR szString, int * pnLength);
};

Below is shown the C# definition of this interface using P/Invoke.

[Guid("F333F56A-B59D-41FE-822D-27989266A535"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITestInterface1
{
   int GetString([MarshalAs(UnmanagedType.LPStr)] StringBuilder builder,
                 ref int pnLength);
}

Now, examine the attributes attached to the interface itself. The Guid attribute is the ID of the interface. The InterfaceType attribute indicates the type of the interface—in this case, that it is an IUnknown-derived interface.

Note: P/Invoke has no way of determining the order of the methods in the interface, and so they must therefore be in the same order as in the .idl file.

About the Author
He first encountered Windows programming using Visual C++/MFC version 1.5 on Windows 3.11 a very long time ago. He is now a senior developer for a business analysis software and consultancy company working in C#. And when he's not programming... hang on, when is he not programming ?

Go to page: 1  2  Next

Downloads

  • CSComInteropExample.zip - Examples source files

    Tools:
    Add www.codeguru.com to your favorites
    Add www.codeguru.com to your browser search box
    IE 7 | Firefox 2.0 | Firefox 1.5.x
    Receive news via our XML/RSS feed







  • RATE THIS ARTICLE:   Excellent  Very Good  Average  Below Average  Poor  

    (You must be signed in to rank an article. Not a member? Click here to register)

    Latest Comments:
    CoCreateInstance/ole32.dll - lantz (09/28/2005)

    View All Comments
    Add a Comment:
    Title:
    Comment:
    Pre-Formatted: Check this if you want the text to display with the formatting as typed (good for source code)



    (You must be signed in to comment on an article. Not a member? Click here to register)


    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

    Solutions
    Whitepapers and eBooks
    Intel PDF: Virtualization Delivers Data Center Efficiency
    Intel eBook: Managing the Evolving Data Center
    Microsoft Article: BitLocker Brings Encryption to Windows Server 2008
    Symantec eBook: The Guide to E-Mail Archiving and Management
    Microsoft Article: RODCs Transform Branch Office Security
    Go Parallel Article: James Reinders on the Intel Parallel Studio Beta Program
    Avaya Article: Advancing the State of the Art in Customer Service
    Adobe Acrobat Connect Pro: Web Conferencing and eLearning Whitepapers
    Avaya Article: Avaya AE Services Provide Rapid Telephony Integration with Facebook
    Go Parallel Article: Getting Started with TBB on Windows
    HP eBook: Storage Networking , Part 1
    MORE WHITEPAPERS, EBOOKS, AND ARTICLES
    Webcasts
    Intel Seminar: Efficiencies in Hardware/Software Virtualization
    HP Webcast: Disaster Recovery Planning
    Go Parallel Video: Performance and Threading Tools for Game Developers
    HP Video: StorageWorks EVA4400 and Oracle
    HP Webcast: Storage Is Changing Fast - Be Ready or Be Left Behind
    MORE WEBCASTS, PODCASTS, AND VIDEOS
    Downloads and eKits
    IBM TCO eKIT: Your IT Budget is Under Attack, Get in Control
    IBM Energy Efficiency eKIT: Learn How to Reduce Costs
    30-Day Trial: SPAMfighter Exchange Module
    Red Gate Download: SQL Toolbelt and free High-Performance SQL Code eBook
    Iron Speed Designer Application Generator
    MORE DOWNLOADS, EKITS, AND FREE TRIALS
    Tutorials and Demos
    Microsoft Article: Silverlight Streaming--Free Video Hosting for All
    Featured Algorithm: Intel Threading Building Blocks - parallel_reduce
    HP Demo: StorageWorks EVA4400
    MORE TUTORIALS, DEMOS AND STEP-BY-STEP GUIDES