title: COM interop passing wrong pointers, with only a single byte of my data
body: <p>I'm having a problem passing pointers to native code using COM. I want to build up a byte array in managed (C#) code and pass that array to native (C++) code. I'm handling the managed-code side, and my colleague owns the native side. Note that I'm much stronger on the managed side, and I've pretty much been using the COM object as written.</p>
  
  <p>The COM signature (simplified) looks this:</p>
  
  <pre><code>unsafe void DoSomething([In] byte* buffer, [In] uint length)
  </code></pre>
  
  <p>And I call it like this:</p>
  
  <pre><code>var arr = File.ReadAllBytes(@"c:\temp\foo.bar");
  fixed (byte* p = arr)
  {
      // let's see what we're actually pointing at
      IntPtr ip = new IntPtr(p);
      Console.WriteLine(ip.ToInt32().ToString("x"));
  
      interop.DoSomething(p, arr.Length);
  }
  </code></pre>
  
  <p>Debugging on the managed side, I see the data I expect at the memory location printed out (using Visual Studio's Memory view). When I debug the unmanaged side, I see the right data at that location as well. But, the pointer doesn't point to the right place! It points to a completely different memory location. That location contains the correct first byte of my data, but garbage for the rest of it. And then, of course, lots of wonderful crashy badness happens.</p>
  
  <p>So, for instance, I see:  </p>
  
  <ul>
  <li>managed side: pointer (<code>p</code>) is 0x1234567, Memory at 0x1234567 contains the contents of my file.</li>
  <li>unmanaged side: pointer (<code>buffer</code>) is 0x5678901, first byte of memory at that location contains the first byte of my file, rest is garbage. Memory at 0x1234567 contains the contents of my file.</li>
  </ul>
  
  <p>I've also tried automatic marshaling:</p>
  
  <pre><code>void DoSomething([In] [MarshalAs(UnmanagedType.LPArray,
                                   ArraySubType = UnmanagedType.U1)]
                        byte[] buffer,
                   [In] uint length)
  </code></pre>
  
  <p>... using straight byte arrays on the managed side; the same result.</p>
  
  <p>And I've tried allocating memory with <code>Marshal.AllocHGlobal</code>, copying data into that with <code>Marshal.Copy</code> and passing the resulting <code>IntPtr</code>, cast to a <code>byte*</code>. Same result.</p>
  
  <p>What the heck am I missing here?</p>
  
  <p><sub>This is a 32-bit process. I've tried smallish (300B) and large (10MB) buffer sizes. C# 3.5, VS 2010.</sub></p>