title: Call between managed and unmanaged code through callback
body: <p>I have been facing a lot of issue in passing string between managed and unmanaged code. After searching and combining codes I have a solution which seems to work. But still I am not sure if it’s the correct implementation.</p>
  
  <p>In my code c# passes a delegate function to c++. Now c++ calls that function whenever required. C++ needs to send string to call back function for which I am using BSTR. That’s how I implemented it.</p>
  
  <p>C#</p>
  
  <pre><code>[DllImport("xyz.dll")]
  public static extern void SetCallback(Callback fn);
  
  public delegate void Callback([MarshalAs(UnmanagedType.BStr)]string str);
  public Callback mInstance;
  
  private void Handler(string text)
  {
    NotifyListeners_uccx(text);
  }
  
  Private void setcallback(){
   mInstance = new Callback(Handler);
   SetCallback(mInstance);  }
  </code></pre>
  
  <p>C++</p>
  
  <pre><code>typedef void (__stdcall *Callback) (BSTR str);
  Callback Handler;
  
  extern "C" 
  {   
        void __declspec(dllexport) __stdcall SetCallback(Callback handler);
        void __declspec(dllexport) __stdcall SendReceiveMessage(BSTR arr1); 
       }
  
   void __stdcall SendReceiveMessage(BSTR arr1) {
     Handler(arr1);
   }
  
  void __stdcall SetCallback(Callback handler1) {
     Handler = handler1;
  }
  
  void CCall::sendmsg(FILE *fp)
  {
  //do some work
      try
  {
      char *str;
      char *Tag_t;
  
      str = new char[2048];
      Tag_t = new char[1024];
  
      sprintf(str, "&lt;body&gt;&lt;Tag1&gt;%d&lt;/Tag1 &gt;&lt;Tag2&gt;%s&lt;/Tag2&gt;",sumNum, SumString);
  
      for (int i = 0; i &lt; sumNum; i++)
      {
  
          sprintf(Tag_t,"&lt;Tag3&gt;%s&lt;/Tag3&gt;",tagString3,m_csqIDs[i],i);
          strcat(str,Tag_t);
      }
      strcat(str,"&lt;/body&gt;");
  
      int wslen = MultiByteToWideChar(CP_ACP, 0, str, strlen(str), 0, 0);
      BSTR bstr = SysAllocStringLen(0, wslen);
      MultiByteToWideChar(CP_ACP, 0, str, strlen(str), bstr, wslen);
      // Use bstr here
      SendReceiveMessage(bstr);
      SysFreeString(bstr);
  
      //SysFreeString(bstr);
      delete[] str;
      delete[] Tag_t;
  }
  catch(std::bad_alloc&amp; exc)
  {
  
      return;
  }
    }
  </code></pre>
  
  <p>Please suggest if this is the correct way to do this?</p>