title: How to get an IntPtr to a struct?
body: <p>I've got a method with the signature</p>
  
  <pre><code>public int Copy(Texture texture, Rect? srcrect, Rect? dstrect)
  </code></pre>
  
  <p><code>Rect</code> is a struct, but I need to allow the caller to pass <code>null</code> (or <code>IntPtr.Zero</code>) to the method as well.</p>
  
  <p>I want to then pass it off to a DLL with the signature</p>
  
  <pre><code>[DllImport("SDL2.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_RenderCopy")]
  internal static extern int RenderCopy(IntPtr renderer, IntPtr texture, IntPtr srcrect, IntPtr dstrect);
  </code></pre>
  
  <p>I was hoping I could do something like the following:</p>
  
  <pre><code>return SDL.RenderCopy(_ptr, texture._ptr, srcrect.HasValue ? (IntPtr)srcrect.Value : IntPtr.Zero, dstrect.HasValue ? (IntPtr)dstrect.Value : IntPtr.Zero);
  </code></pre>
  
  <p>But I can't cast the struct like that. Is there some other way I can get an <code>IntPtr</code> out of it?</p>
  
  <hr>
  
  <p>There alternative is to create 4 overloads: </p>
  
  <ul>
  <li><code>ref Rect, ref Rect</code></li>
  <li><code>IntPtr, IntPtr</code></li>
  <li><code>ref Rect, IntPtr</code></li>
  <li><code>IntPtr, ref Rect</code></li>
  </ul>
  
  <p>which could get even messier if I ever need to pass more than 2 struct pointers.</p>
  
  <hr>
  
  <p>I came up with a solution, but I have some questions about it:</p>
  
  <pre><code>public int Copy(Texture texture, Rect? srcrect=null, Rect? dstrect=null)
  {
      return SDL.RenderCopy(_ptr, texture._ptr, srcrect.HasValue ? StructToPtr(srcrect) : IntPtr.Zero, dstrect.HasValue ? StructToPtr(dstrect) : IntPtr.Zero);
  }
  
  private static IntPtr StructToPtr(object obj)
  {
      var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
      Marshal.StructureToPtr(obj, ptr, false);
      return ptr;
  }
  </code></pre>
  
  <p>Had I used <code>ref Rect</code> I wouldn't have had to allocate memory for the struct -- what does that do differently than this does?</p>
  
  <hr>
  
  <p>I did some experimentation. The <code>ref Rect</code> solution runs at about the same speed as <del>converting a <code>Rect</code> to an <code>IntPtr</code></del> generating an <code>IntPtr</code> for a <code>Rect</code>, which leads me to suspect that C# is doing something very similar under the hood when you use refs. As soon as I make it a <code>Rect?</code> and add the conditional logic to the method it runs up to 50% slower... so the 4-overload route would probably be the fastest. However, we're talking 100-150ms for 100K iterations, which means the method itself is super cheap, which is probably why the conditionals have such a notable impact. As such, I'm sticking with my custom <code>StructToPtr</code> solution as it's the simplest solution.</p>