COM - Implementing a simple COM object using .NET CCW

We will create a COM object in C# and call it from C++.


Step 1. Create a new C# assembly for your COM object

File ... New ... Project ... Visual C# ... Class Library (.NET Framework). I used the project name zuga
Project ... Properties ... Signing ... Sign the assembly. Choose a strong name key file. Create new or select existing.


Step 2. Define and implement your COM interface. Add MessageBoxClass.cs below:


  using System;
  using System.Runtime.InteropServices;
  
  namespace zuga
  {
      [
          Guid("5F397ABD-7CDE-4708-B9D2-7E9363A70E40"),
          InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
      ]
      public interface IMessageBox
      {
          int ShowMessageBox(string text, string caption, uint type);
      };
  
      [
          Guid("24375867-7CC0-4278-B479-91091B9EFC87"),
          ClassInterface(ClassInterfaceType.None),
          ProgId("Zuga.MessageBox.1")
      ]
      public class MessageBoxClass : IMessageBox
      {
          [DllImport("user32.dll", CharSet = CharSet.Unicode)]
          public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
  
          public int ShowMessageBox(string text, string caption, uint type)
          {
              return MessageBox(IntPtr.Zero, text, caption, type);
          }
      }
  }
  

Step 3. Register the .NET assembly with COM.

  regasm -tlb -codebase zuga.dll
  
  Microsoft .NET Framework Assembly Registration Utility version 4.6.1586.0
  for Microsoft .NET Framework version 4.6.1586.0
  Copyright (C) Microsoft Corporation.  All rights reserved.
  
  Types registered successfully
  
  Assembly exported to 'C:\...\zuga\bin\Debug\zuga.tlb', and the type library was registered successfully
  

Ads by Google

Step 4. Create a C++ console application to test the COM object.

File ... New ... Project ... Other Languages ... Visual C++ ... Win32 Console Application


  // zugaTest.cpp : Defines the entry point for the console application.
  //
  
  #include "stdafx.h"
  #include <windows.h>
  #include <comdef.h>
  #import "C:\...\zuga\bin\Debug\zuga.tlb" raw_interfaces_only
  
  // fwd decs
  HRESULT ShowMessageBox();
  
  
  int _tmain(int argc, _TCHAR* argv[])
  {
      HRESULT hr = ::CoInitialize(NULL);
      
      hr = ShowMessageBox();
      
      ::CoUninitialize();
      
      return 0;
  }
  
  static HRESULT ShowMessageBox()
  {
      zuga::IMessageBoxPtr pMessageBox;
      HRESULT hr = pMessageBox.CreateInstance(__uuidof(zuga::MessageBoxClass));
      
      long retval = 0;
      _bstr_t text = "hello from c++";
      _bstr_t caption = "console test app";
      unsigned long type = MB_ICONINFORMATION;
      
      hr = pMessageBox->ShowMessageBox(text, caption, type, &retval);
      
      return hr;
  }
  

The output:

[output.gif]

Ads by Google

Ask a question, send a comment, or report a problem - click here to contact me.

© Richard McGrath