title: Using a managed buffer in native code after the call returns
body: <p>I have a buffer I am allocating in C# and passing to native code. I then save a pointer to that buffer:</p>
  
  <p><strong>Header Definitions</strong></p>
  
  <pre class="lang-c++ prettyprint-override"><code>// called when a meter is attached
  typedef void(__cdecl * lpfnMeterAttachCallback)();
  
  extern lpfnMeterAttachCallback frMeterAttachCallback;
  
  // called when a meter is detached
  typedef void(__cdecl * lpfnMeterDetachCallback)();
  
  extern lpfnMeterAttachCallback frMeterDetachCallback;
  
  
  // called when a meter is detached
  typedef void(__cdecl * lpfnMeterReadCompleteCallback)();
  
  extern lpfnMeterReadCompleteCallback frMeterReadCompleteCallback;
  
  extern char* frbuffer;
  </code></pre>
  
  <p><strong>Main</strong></p>
  
  <pre class="lang-c++ prettyprint-override"><code>lpfnMeterAttachCallback frMeterAttachCallback;
  lpfnMeterDetachCallback frMeterDetachCallback;
  lpfnMeterReadCompleteCallback frMeterReadCompleteCallback;
  char* frbuffer;
  
  extern "C" __declspec(dllexport) void __cdecl InitDriver(
      lpfnMeterAttachCallback meterAttachCallback,
      lpfnMeterDetachCallback meterDetachCallback,
      lpfnMeterReadCompleteCallback meterReadCompleteCallback, char* buffer)
  {
      frMeterAttachCallback = meterAttachCallback;
      frMeterDetachCallback = meterDetachCallback;
      frMeterReadCompleteCallback = meterReadCompleteCallback;
      frbuffer = buffer;
  ...
  }
  </code></pre>
  
  <p>and later in a background call, fill it as so:</p>
  
  <pre><code>JSONValue testSS = ss-&gt;GetJSON();
  std::string help = *testSS;
  strcpy(frbuffer, help.c_str());
  if (frMeterReadCompleteCallback) frMeterReadCompleteCallback();
  </code></pre>
  
  <p>However my string comes back empty, or as corrupted data. Ideally, I wanted to have a string passed back to my delegate and then use that, but ran into InterOp issues trying to do so. </p>
  
  <p><strong>C#:</strong></p>
  
  <pre><code>[DllImport("MyDLL.dll", CallingConvention = CallingConvention.Cdecl)]
  public static extern void InitDriver(MeterAttachCallback meterAttachCallback,
          MeterDetachCallback meterDetachCallback,
          MeterReadCompleteCallback meterReadCompleteCallback, StringBuilder sb);
  
  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  public delegate void MeterAttachCallback();
  
  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  public delegate void MeterDetachCallback();
  
  
  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  public delegate void MeterReadCompleteCallback();
  
  static public void OnMeterAttach()
  {
      Console.WriteLine("OnMeterAttach");
  }
  
  static public void OnMeterDetach()
  {
      Console.WriteLine("OnMeterDetach");
  }
  
  static StringBuilder sb = new StringBuilder(10 * 1024 * 1024); //10MB
  
  static public void OnMeterReadComplete()
  {
      Console.WriteLine("OnMeterReadComplete; JSON:", sb.ToString());
  }
  
  static void Main(string[] args)
  {
      InitApolloCppDriver(OnMeterAttach, OnMeterDetach, OnMeterReadComplete, sb);
  
      Console.ReadLine();
  }
  </code></pre>
  
  <p>Am I writing/reading the buffer incorrectly, or should I be implementing this in a different way? </p>