title: Failed to cast result of Marshal.GetActiveObject for COM interop wrapper
body: <p>I'm struggling to work out how to access a COM interface provided by a C++ application and use it from a C# .NET application.</p>
  
  <p>I try to access my COM object (which is provided by a running process) from my C# app like this:</p>
  
  <pre><code>object obj = Marshal.GetActiveObject("MyLibrary.Application");
  MyLibrary.IMainApp app = (MyLibrary.IMainApp)obj;
  </code></pre>
  
  <p>The value of <code>obj</code> is non-null, but when I try to cast it I get <code>System.InvalidCastException</code>.</p>
  
  <p>I tried implementing a custom wrapper and also linked against a DLL produced by <code>TlbImp.exe</code>.  Both produced the same exception.</p>
  
  <p>There seems to be a lot of documentation regarding interop, but it's not making sense to me -- mostly because I'm not COM-savvy (I am stuck maintaining code that someone else developed), and am entering the scary world of C#, .NET and WPF by diving headlong into it.</p>
  
  <p>Here's what I have on the C++ end....</p>
  
  <p><strong>IDL File</strong></p>
  
  <p>Actually, the extension is <code>.odl</code>.  I don't know if that's a different thing.  Note that I've replaced the GUIDs with placeholders like <code>GUID-1</code>, <code>GUID-2</code> <em>etc</em>...</p>
  
  <pre><code>import "oaidl.idl";
  
  [ uuid(GUID-1), helpstring("My Type Library"), version(1.1) ]
  library MyLibrary
  {
      importlib("stdole32.tlb");
  
      //  Primary dispatch interface for CMainApp
  
      [ uuid(GUID-2) ]
      dispinterface IMainApp
      {
      properties:
          [id(1)] BOOL Mode;
  
      methods:
          [id(2)] void Quit();
          [id(3)] void LogEventMessage(BSTR szMessageType, BSTR szMessage);
          [id(4)] BOOL GetNoteDetails(BSTR szQualifiedName, BSTR* lpbstrOperator, DATE* lpdtDate);
      };
  
      //  Class information for CMainApp
      [ uuid(GUID-3) ]
      coclass Application
      {
          [default] dispinterface IMainApp;
      };
  };
  </code></pre>
  
  <p><strong>Example Usage</strong></p>
  
  <p>When another C++ application wants to call a function (<em>eg</em> <code>Quit</code>), they do this:</p>
  
  <pre><code>CLSID       clsid;
  HRESULT     hr;
  LPUNKNOWN   lpUnk;
  LPDISPATCH  lpDisp;
  BOOL        bReturn = FALSE;
  
  // Get Class ID
  if (CLSIDFromProgID( OLESTR("MyLibrary.Application"), &amp;clsid ) == S_OK )
  {
      // Get Active Object from ROT
      if ( ( hr = GetActiveObject( clsid, NULL, &amp;lpUnk ) ) == S_OK )
      {
          hr = lpUnk-&gt;QueryInterface( IID_IDispatch, (LPVOID*)&amp;lpDisp );
          lpUnk-&gt;Release();
          if ( hr == S_OK )
          {
              CMainApp oMainApp;
              oMainApp.AttachDispatch( lpDisp );
  
              TRY
              {
                  oMainApp.Quit();
                  bReturn = TRUE;
              }
              CATCH( CException, e )
              {
                  bReturn = FALSE;
              }
              END_CATCH
          }
      }
  }
  </code></pre>
  
  <p>The class <code>CMainApp</code> seems to have been auto-generated by the IDL compiler.  That file is compiled into the project that wants to use it, and basically does a whole lot of <code>InvokeHelper</code> calls.  I'm happy enough to accept this is just the way it works, and I hope that C# is less convoluted.</p>
  
  <p><strong>Attempt to wrap in C#</strong></p>
  
  <p>I followed an MSDN guide on COM interop in C#.  It suggested I could use <code>TlbImp.exe</code> but that threw up enough warnings to put me off.  Besides, I don't want to distribute another DLL.  So I took the other approach of writing a wrapper.</p>
  
  <p>This is what I wrote:</p>
  
  <pre><code>using System.Runtime.InteropServices;
  
  namespace MyLibrary
  {
      // Declare MainApp COM coclass
      [ComImport, Guid("GUID-3")]
      class MainApp
      {
      }
  
      [Guid("GUID-2"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
      interface IMainApp
      {
          public void Quit();
  
          public void LogEventMessage(
              [In, MarshalAs(UnmanagedType.BStr)] string szMessageType,
              [In, MarshalAs(UnmanagedType.BStr)] string szMessage );
  
          public bool GetNoteDetails(
              [In, MarshalAs(UnmanagedType.BStr)] string szQualifiedName,
              [Out, MarshalAs(UnmanagedType.BStr)] out string lpbstrOperator );
              out DateTime lpdtDate );
      }
  }
  </code></pre>
  
  <hr>
  
  <p>Can someone gimme a hand to understand this?  Perhaps point out a totally obvious stupid mistake that I've made? =)</p>