title: Using a managed COM object  in C++
body: <p>I've followed a number of detailed tutorials on how to use a COM object in C++. I'm using VS 2010 pro. I made a new solution called <code>TestComInterop</code>. Made a C# project called <code>TestMath</code>. Made it com visible by selecting the option in <code>properties-&gt;Assembly Information-&gt;Make assembly COM-visible</code>. I then went to the Signing property, signed the Assembly called <code>MyMathCom.snk</code> (no password). I then used the <code>GUID generator</code> and made 2 GUID's. Then put this code into my program and compiled. (success)</p>
  
  <pre><code>using System.Runtime.InteropServices;
  namespace TestMath
  {
      [Guid("599AD473-B0A9-4A6E-B260-CF6FDEBF151B"),InterfaceType(ComInterfaceType.InterfaceIsDual)]
      public interface IClass1
      {
          void AddNumbers(byte[] array);
      }
      [Guid("62FBC3A9-E2C0-4B53-9BF3-FDE22AA0CFF2"),ClassInterface(ClassInterfaceType.None)]
      public class Class1 : IClass1
      {
  
          public void AddNumbers(byte[] array)
          {
              ulong number = 0;
              foreach (var item in array)
              {
                  number += item;
              }
              System.Console.WriteLine("The answer is {0}", number);
              System.Windows.Forms.MessageBox.Show("DOrk");
          }
      }
  }
  </code></pre>
  
  <p>I then made a C++ project for Console App. Allowed MFC.</p>
  
  <p>Then i added a <code>Typelib</code> MFC class. I was able to use the drop down box to find <code>TestMath&lt;1.0&gt;</code> and it had my <code>iClass1</code>. I selected that and it made the header file for me</p>
  
  <pre><code>// Machine generated IDispatch wrapper class(es) created with Add Class from Typelib Wizard
  
  #import "C:\\Users\\rsny\\Desktop\\TestComInterop\\TestComInterop\\TestMath\\bin\\Debug\\TestMath.tlb" no_namespace
  // CClass1 wrapper class
  
  class CClass1 : public COleDispatchDriver
  {
  public:
      CClass1(){} // Calls COleDispatchDriver default constructor
      CClass1(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {}
      CClass1(const CClass1&amp; dispatchSrc) : COleDispatchDriver(dispatchSrc) {}
  
      // Attributes
  public:
  
      // Operations
  public:
  
  
      // IClass1 methods
  public:
      void AddNumbers(SAFEARRAY * array)
      {
          static BYTE parms[] = {VTS_NONE} ;
          InvokeHelper(0x60020000, DISPATCH_METHOD, VT_EMPTY, NULL, parms, array);
      }
  
      // IClass1 properties
  public:
  
  };
  </code></pre>
  
  <p>compiled, and it made the <code>tlh</code> and <code>tli</code> files for me.. success..</p>
  
  <p>So then last step is to run my code. Opened up <code>TestComInterop.cpp</code> and this is were I can't find a "standard" way of doing it. I've tried various different things, but wasn't sure what to put in... here is my code for that</p>
  
  <pre><code>// TestComInterop.cpp : Defines the entry point for the console application.
  //
  
  #include "stdafx.h"
  #include "TestComInterop.h"
  #include "CClass1.h"
  
  #ifdef _DEBUG
  #define new DEBUG_NEW
  #endif
  
  
  // The one and only application object
  
  CWinApp theApp;
  
  using namespace std;
  
  int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  {
      int nRetCode = 0;
  
      HMODULE hModule = ::GetModuleHandle(NULL);
  
      if (hModule != NULL)
      {
          // initialize MFC and print and error on failure
          if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
          {
              // TODO: change error code to suit your needs
              _tprintf(_T("Fatal Error: MFC initialization failed\n"));
              nRetCode = 1;
          }
          else
          {
              // TODO: code your application's behavior here.
          }
      }
      else
      {
          // TODO: change error code to suit your needs
          _tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
          nRetCode = 1;
      }
      CClass1* myMath = new CClass1;
      myMath-&gt;CreateDispatch("62FBC3A9-E2C0-4B53-9BF3-FDE22AA0CFF2");
      //bool result = myMath.
      if (myMath)
          cout &lt;&lt; "AWESOME" &lt;&lt; endl;
      else
          cout &lt;&lt; "LAME" &lt;&lt; endl;
  
      unsigned char numbers[5] = {0x01,0x02,0x03,0x04,0x05};
      myMath-&gt;AddNumbers((SAFEARRAY*)numbers);
      delete myMath;
      getchar();
      return nRetCode;
  }
  </code></pre>
  
  <p>Now I'm expecting it to paste the answer to my console.. but nothing. I'm also expecting it to display a message box... nothing. to say the least I'm a newb when it comes to COM objects. So far making this hasn't been too difficult with all the tools and so forth... but for the life of me I can't get this to work. </p>
  
  <p>Just in case it's needed here are my <code>tlh</code> and <code>tli</code> files.</p>
  
  <pre><code>// Created by Microsoft (R) C/C++ Compiler Version 10.00.30319.01 (e323d9ba).
  //
  // c:\users\rsny\desktop\testcominterop\testcominterop\testcominterop\debug\testmath.tli
  //
  // Wrapper implementations for Win32 type library C:\\Users\\rsny\\Desktop\\TestComInterop\\TestComInterop\\TestMath\\bin\\Debug\\TestMath.tlb
  // compiler-generated file created 09/14/12 at 12:08:08 - DO NOT EDIT!
  
  #pragma once
  
  //
  // interface IClass1 wrapper method implementations
  //
  
  inline HRESULT IClass1::AddNumbers ( SAFEARRAY * array ) {
      HRESULT _hr = raw_AddNumbers(array);
      if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
      return _hr;
  }
  
  // Created by Microsoft (R) C/C++ Compiler Version 10.00.30319.01 (e323d9ba).
  //
  // c:\users\rsny\desktop\testcominterop\testcominterop\testcominterop\debug\testmath.tlh
  //
  // C++ source equivalent of Win32 type library C:\\Users\\rsny\\Desktop\\TestComInterop\\TestComInterop\\TestMath\\bin\\Debug\\TestMath.tlb
  // compiler-generated file created 09/14/12 at 12:08:08 - DO NOT EDIT!
  
  #pragma once
  #pragma pack(push, 8)
  
  #include &lt;comdef.h&gt;
  
  //
  // Forward references and typedefs
  //
  
  struct __declspec(uuid("d29ff1b5-bf10-4bbe-9bd9-cb5346f4bfaf"))
  /* LIBID */ __TestMath;
  struct __declspec(uuid("599ad473-b0a9-4a6e-b260-cf6fdebf151b"))
  /* dual interface */ IClass1;
  struct /* coclass */ Class1;
  
  //
  // Smart pointer typedef declarations
  //
  
  _COM_SMARTPTR_TYPEDEF(IClass1, __uuidof(IClass1));
  
  //
  // Type library items
  //
  
  struct __declspec(uuid("599ad473-b0a9-4a6e-b260-cf6fdebf151b"))
  IClass1 : IDispatch
  {
      //
      // Wrapper methods for error-handling
      //
  
      HRESULT AddNumbers (
          SAFEARRAY * array );
  
      //
      // Raw methods provided by interface
      //
  
        virtual HRESULT __stdcall raw_AddNumbers (
          /*[in]*/ SAFEARRAY * array ) = 0;
  };
  
  struct __declspec(uuid("62fbc3a9-e2c0-4b53-9bf3-fde22aa0cff2"))
  Class1;
      // interface _Object
      // [ default ] interface IClass1
  
  //
  // Wrapper method implementations
  //
  
  #include "c:\users\rsny\desktop\testcominterop\testcominterop\testcominterop\debug\testmath.tli"
  
  #pragma pack(pop)
  </code></pre>