Export (0) Print
Expand All
21 out of 35 rated this helpful - Rate this topic

COM Interop Part 2: C# Server Tutorial

Visual Studio .NET 2003

COM Interop allows COM developers to access managed code as easily as they access other COM objects. This tutorial demonstrates using a C# server with a C++ COM client. It also explains the following activities:

  • How to create the C# server
  • How to create the COM client

The tutorial also briefly demonstrates the marshaling that is automatically applied between managed and unmanaged components.

COM Interop Part 1: C# Client Tutorial shows the fundamentals of using C# to interoperate with COM objects and is a prerequisite for this tutorial. For an overview of both tutorials, see COM Interop Tutorials.

Sample Files

See COM Interop Part 2 Sample to download and build the sample files discussed in this tutorial.

Further Reading

Tutorial

This tutorial demonstrates the following activities to create the C# server:

  • How to use the Guid attribute on interfaces and classes to expose them as COM objects and how to generate a globally unique identifier (GUID) for the Guid attribute.
  • How to use RegAsm to register a .NET Framework program for use by COM clients and create a type library (.tlb file) from a .NET Framework program.

The tutorial also demonstrates the following activities to create the COM client:

  • How to export managed servers and how to use them to create COM objects.
  • How to import the .tlb file, generated by RegAsm, into the COM client and how to use CoCreateInstance to create an instance of a .NET Framework coclass.
    Note   To create a GUID for interfaces and coclasses that you export to COM clients, use the tool Guidgen.exe, shipped as part of Visual Studio. Guidgen allows you to choose the format in which the GUID is expressed so you don't have to retype it. For more information on Guidgen, see the Knowledge Base article Q168318 "XADM: Guidgen.exe Available Only for Intel Platforms." KB articles are available in the MSDN Library and on the Web at http://support.microsoft.com.

Example

This example consists of two files:

  • A C# file, CSharpServer.cs, that creates the CSharpServer.dll file. The .dll is used to create the file CSharpServer.tlb.
  • A C++ file, COMClient.cpp, that creates the executable client, COMClient.exe.

File 1: CSharpServer.cs

// CSharpServer.cs
// compile with: /target:library
// post-build command: regasm CSharpServer.dll /tlb:CSharpServer.tlb

using System;
using System.Runtime.InteropServices;
namespace CSharpServer
{
   // Since the .NET Framework interface and coclass have to behave as 
   // COM objects, we have to give them guids.
   [Guid("DBE0E8C4-1C61-41f3-B6A4-4E2F353D3D05")]
   public interface IManagedInterface
   {
      int PrintHi(string name);
   }

   [Guid("C6659361-1625-4746-931C-36014B146679")]
   public class InterfaceImplementation : IManagedInterface
   {
      public int PrintHi(string name)
      {
         Console.WriteLine("Hello, {0}!", name);
         return 33;
      }
   }
}

File 2: COMClient.cpp

// COMClient.cpp
// Build with "cl COMClient.cpp"
// arguments: friend

#include <windows.h>
#include <stdio.h>

#pragma warning (disable: 4278)

// To use managed-code servers like the C# server, 
// we have to import the common language runtime:
#import <mscorlib.tlb> raw_interfaces_only

// For simplicity, we ignore the server namespace and use named guids:
#if defined (USINGPROJECTSYSTEM)
#import "..\RegisterCSharpServerAndExportTLB\CSharpServer.tlb" no_namespace named_guids
#else  // Compiling from the command line, all files in the same directory
#import "CSharpServer.tlb" no_namespace named_guids
#endif
int main(int argc, char* argv[])
{
   IManagedInterface *cpi = NULL;
   int retval = 1;

   // Initialize COM and create an instance of the InterfaceImplementation class:
   CoInitialize(NULL);
   HRESULT hr = CoCreateInstance(CLSID_InterfaceImplementation,
               NULL, CLSCTX_INPROC_SERVER,
               IID_IManagedInterface, reinterpret_cast<void**>(&cpi));

   if (FAILED(hr))
   {
      printf("Couldn't create the instance!... 0x%x\n", hr);
   }
   else
   {
      if (argc > 1)
      {
         printf("Calling function.\n");
         fflush(stdout);
         // The variable cpi now holds an interface pointer 
         // to the managed interface.
         // If you are on an OS that uses ASCII characters at the 
         // command prompt, notice that the ASCII characters are 
         // automatically marshaled to Unicode for the C# code.
         if (cpi->PrintHi(argv[1]) == 33)
            retval = 0;
         printf("Returned from function.\n");
      }
      else
         printf ("Usage:  COMClient <name>\n");
      cpi->Release();
      cpi = NULL;
   }

   // Be a good citizen and clean up COM:
   CoUninitialize();
   return retval;
}

Output

The executable client can be invoked with the command line: COMClient <name>, where <name> is any string you want to use, for example, COMClient friend.

Calling function.
Hello, friend!
Returned from function.

In the sample IDE project, set the Command Line Arguments property in the project's Property Pages to the desired string (for example, "friend").

See Also

C# Tutorials | COM Interop Tutorials

Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.