我写了一个辅助方法,
internal static IntPtr StructToPtr(object obj)
{
var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
Marshal.StructureToPtr(obj, ptr, false);
return ptr;
}
它接受一个 struct
并将其转换为一个 IntPtr
。我使用它的方式如下:
public int Copy(Texture texture, Rect srcrect, Rect dstrect)
{
return SDL.RenderCopy(_ptr, texture._ptr, Util.StructToPtr(srcrect), Util.StructToPtr(dstrect));
}
问题在于我只需要那个IntPtr
一刹那,这样我就可以将它传递给C DLL了。[DllImport("SDL2.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_RenderCopy")]
internal static extern int RenderCopy(IntPtr renderer, IntPtr texture, IntPtr srcrect, IntPtr dstrect);
我其实不想担心释放它的问题;否则我的一行代码就会变成六行:
public int Copy(Texture texture, Rect? srcrect=null, Rect? dstrect=null)
{
var srcptr = Util.StructToPtr(srcrect);
var dstptr = Util.StructToPtr(dstrect);
var result = SDL.RenderCopy(_ptr, texture._ptr, srcptr, dstptr);
Marshal.FreeHGlobal(srcptr);
Marshal.FreeHGlobal(dstptr);
return result;
}
有没有更好的方法来做到这一点?C#会清理它分配的任何内存吗?
如果不行,那么我是否可以将对SDL.RenderCopy
的调用包装在一些using
语句中,以便我不必进行所有这些临时变量和显式释放的无聊操作?
implicit
转换成IntPtr
,这样就无需使用.Ptr
就能将其传递给他的 API 调用。 - Jonathon Reinhartnull
并将Ptr
初始化为IntPtr.Zero
。 - mpenctor
的写法为if (Ptr != null)
,我认为这是错误的。ctor
应该检查obj
是否为空,并相应地设置Ptr
。请参考Mark于2013年7月10日4:40提出的建议。 - Kent