title: Handle C# events in C++ unmanaged code using COM-Interop
body: <p>I have a TcpSocketServer written in C# and I want to use it in native C++ without CLI. The class rises events on client connection/disconnection and when data is received. Untill now I got the server working and accepting connection, however I still can't send/receive data.</p>
  
  <p>Notice that this is one of several classes I need to work with, so please do not suggest me to use native C++ sockets.</p>
  
  <p>The (relevant) C# code is bellow:</p>
  
  <pre class="lang-cs prettyprint-override"><code>[ComVisible(true)]
  public delegate void TcpClientConnectedEventHandler(Socket s);
  
  [ComVisible(true)]
  public delegate void TcpClientDisconnectedEventHandler(EndPoint ep);
  
  [ComVisible(true)]
  public delegate void TcpDataReceivedEventHandler(TcpPacket p);
  
  [ComVisible(true)]
  [Guid("7cf49dcd-c11b-4e94-9f73-d5a24fe027c3")]
  public interface ISocketTcpServer
  {
      event TcpClientConnectedEventHandler ClientConnected;
      event TcpClientDisconnectedEventHandler ClientDisconnected;
      event TcpDataReceivedEventHandler DataReceived;
  
      [ComVisible(true)]
      int SendToAll(byte[] buffer);
  }
  </code></pre>
  
  <p>Now, in C++ I have the following (relevant) code:</p>
  
  <pre class="lang-c prettyprint-override"><code>// Function Prototypes
  void onClientConnected();
  void onClientDisconnected();
  void onDataReceived(ITcpPacket *packet);
  VARIANT_BOOL started(ISocketTcpServer *server);
  long send(ISocketTcpServer *server, char *s);
  
  int main(int argc, char* argv[])
  {
      ISocketTcpServer *server = NULL;
      _TcpDataReceivedEventHandler *dataReceivedPtr = NULL;
      _TcpClientConnectedEventHandler *clientConnectedPtr = NULL;
      _TcpClientDisconnectedEventHandler *clientDisconnectedPtr = NULL;
      char sInput[1024];
  
      std::cout &lt;&lt; "C# Sockets Interop example.\r\n";
  
      // Initialize COM.
      CoInitialize(NULL);
  
      // Create the interface pointers.
      HRESULT hr = CoCreateInstance(__uuidof(SocketTcpServer), NULL,
          CLSCTX_INPROC_SERVER, __uuidof(ISocketTcpServer), (void **)&amp;server);
  
      if((hr != S_OK) || (server == NULL))
      {
          std::cout &lt;&lt; "Create instance failed\r\n";
          CoUninitialize();
          return 0;
      }
  
      // Configure TCP Server
      server-&gt;put_Port(2000);
      dataReceivedPtr = (_TcpDataReceivedEventHandler *)&amp;onDataReceived;
      clientConnectedPtr = (_TcpClientConnectedEventHandler *)&amp;onClientConnected;
      clientDisconnectedPtr =
          (_TcpClientDisconnectedEventHandler *)&amp;onClientDisconnected;
  
      /* HERE IS WHERE I SET UP THE EVENTS */
      server-&gt;add_ClientConnected(clientConnectedPtr);
      server-&gt;add_ClientDisconnected(clientDisconnectedPtr);
      server-&gt;add_DataReceived(dataReceivedPtr);
  
      // Start TCP Server
      std::cout &lt;&lt; "Starting TCP Server on port 2000.\r\n";
      server-&gt;Start();
      while(!started(server)) Sleep(100);
      while(started(server))
      {
          std::cin &gt;&gt; sInput;
          send(server, sInput);
      }
  
      // Uninitialize COM.
      CoUninitialize();
      return 0;
  }
  
  long send(ISocketTcpServer *server, char *s)
  {
      long result = 0;
      server-&gt;SendToAll((SAFEARRAY *) s, &amp;result);
      return result;
  }
  </code></pre>
  
  <p>All other functions have its definition and works fine, so I did'n include them.</p>
  
  <p>The main question is: How must be declared the functions which will handle the events to get it work. I supose they are not working because they do not match the asociated delegate, but I can not access the classes Socket and EndPoint of the .NET Framework.</p>
  
  <p>Also the method</p>
  
  <pre class="lang-cs prettyprint-override"><code>SendToAll(byte[] buffer):int
  </code></pre>
  
  <p>mapped to the function</p>
  
  <pre class="lang-c prettyprint-override"><code>SendToAll(SAFEARRAY *buffer, long *pRetVal):HRESULT
  </code></pre>
  
  <p>but may be this is a cast problem.</p>
  
  <p>Any help or tip you could give me will be usefull.</p>
  
  <p>Taanks in advance.</p>