我有一个带签名的方法
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
我提出了一个解决方案,但我对此有一些疑问:
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
解决方案的运行速度与将的速度大约相同,为Rect
转换为IntPtr
IntPtr
生成Rect
,这让我怀疑当你使用refs时,C#正在做一些非常相似的事情。一旦我将它设为Rect?
并将条件逻辑添加到方法中,它运行速度就会慢50%......因此4重载路径可能是最快的。然而,我们谈论100K迭代100-150ms,这意味着该方法本身是超级便宜的,这可能是条件具有如此显着影响的原因。因此,我坚持使用我的自定义StructToPtr
解决方案,因为这是最简单的解决方案。
答案 0 :(得分:6)
您还必须为结构分配和释放内存。
关于这个主题的好博客可以在http://www.developerfusion.com/article/84519/mastering-structs-in-c/
找到答案 1 :(得分:-2)
这里有我所拥有的,我使用的是来自M $ DLL的API,原型是这样的:
HRESULT C_API(LPCWSTR name, PSTRUCT_WHATEVER *ppStruct);
结构定义如下:
typedef struct whatever {
LPCWSTR x;
LPCWSTR y;
}
在C#中,我定义了以下内容:
[StructLayout(LayoutKind.Sequential)]
public class WHATEVER {
public IntPtr x;
public IntPtr y;
}
[DllImport("msdll.dll", SetLastError=false, CharSet=CharSet.Unicode)]
public static extern long C_API(String name, out IntPtr ppStruct);
使用它:
IntPtr s;
long HR = C_API("myname", out s);
WHATEVER pInfo = (WHATEVER) Marshal.PtrToStructure(s, typeof(WHATEVER));
String mystring = Marshal.PtrToStringAuto(pInfo.x);
此时mystring ="这是一个字符串&#34 ;;