I have a method with a signature
public int Copy(Texture texture, Rect? srcrect, Rect? dstrect)
Rect is a structure, but I need to allow the caller to pass a null (or IntPtr.Zero ) method.
I want to pass it to a signed DLL
[DllImport("SDL2.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_RenderCopy")] internal static extern int RenderCopy(IntPtr renderer, IntPtr texture, IntPtr srcrect, IntPtr dstrect);
I was hoping I could do something like the following:
return SDL.RenderCopy(_ptr, texture._ptr, srcrect.HasValue ? (IntPtr)srcrect.Value : IntPtr.Zero, dstrect.HasValue ? (IntPtr)dstrect.Value : IntPtr.Zero);
But I can not use such a structure. Is there any other way to get IntPtr from this?
An alternative would be to create 4 overloads:
ref Rect, ref RectIntPtr, IntPtrref Rect, IntPtrIntPtr, ref Rect
which can become even more messy if I ever need to pass in more than two pointers to a structure.
I came up with a solution, but I have some questions about this:
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; }
If I used ref Rect , I would not have to allocate memory for the structure - what does it do differently than it does?
I experimented a bit. The ref Rect solution runs at about the same speed as converting a Rect to IntPtr by generating IntPtr for Rect , which makes me suspect that C # is doing something very similar under the hood when you use refs. As soon as I do this Rect? and add conditional logic to the method, it will work 50% slower ... so the 4-overload route will probably be the fastest. Nevertheless, we are talking about 100-150 ms for iterations of 100 KK, which means that the method itself is super cheap, and this is probably why conventions have such a noticeable effect. Thus, I stick with my custom StructToPtr solution, as this is the simplest solution.