我有一个带有签名的方法
public int Copy(Texture texture, Rect? srcrect, Rect? dstrect)
Rect
是一个结构,但我还需要允许调用者将null
(或IntPtr.Zero
)传递给该方法。
然后我想将其传递给带有签名的 DLL
[DllImport("SDL2.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_RenderCopy")]
internal static extern int RenderCopy(IntPtr renderer, IntPtr texture, IntPtr srcrect, IntPtr dstrect);
我希望我可以做以下事情:
return SDL.RenderCopy(_ptr, texture._ptr, srcrect.HasValue ? (IntPtr)srcrect.Value : IntPtr.Zero, dstrect.HasValue ? (IntPtr)dstrect.Value : IntPtr.Zero);
但我不能像那样转换结构。有没有其他方法可以让我IntPtr
摆脱它?
另一种方法是创建 4 个重载:
ref Rect, ref Rect
IntPtr, IntPtr
ref Rect, IntPtr
IntPtr, ref Rect
如果我需要传递超过 2 个结构指针,这可能会变得更加混乱。
我想出了一个解决方案,但我对此有一些疑问:
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;
}
如果我使用过ref Rect
,我就不必为结构分配内存——这与它有什么不同?
我做了一些实验。该ref Rect
解决方案的运行速度与将 a 转换Rect
为IntPtr
IntPtr
为 a生成一个Rect
,这让我怀疑当你使用 refs 时 C# 在幕后做了非常相似的事情。一旦我将其设置为 aRect?
并将条件逻辑添加到方法中,它的运行速度就会慢 50%……所以 4-overload 路线可能是最快的。然而,我们所说的 100K 迭代需要 100-150 毫秒,这意味着该方法本身非常便宜,这可能就是条件语句具有如此显着影响的原因。因此,我坚持使用我的自定义StructToPtr
解决方案,因为它是最简单的解决方案。