如何struct使用pinvoke 处理从C#调用的dll方法中的可选参数?例如,不存在时应传递lpSecurityAttributes此处的参数null。
struct
lpSecurityAttributes
null
传递的正确方法struct似乎是使用ref,但不能具有可选参数,也不能采用null一般参数。
ref
有什么方法可以做到这一点?
class
我认为这种方法是最简单的。只需将声明struct为class:
[StructLayout(LayoutKind.Sequential)] public class CStruct { //member-list }
然后声明您的方法:
[DllImport("mydll.dll", OptionName = optionValue, ...)] static extern int DLLFunction(CStruct cStruct, ...);
如果您的可选参数恰好是最后一个,则可以改用它CStruct cStruct = null作为参数。这使您可以排除它而不是null显式传递。您还可以编写一个使用该方法的包装器方法,并确保可选参数排在最后。
CStruct cStruct = null
IntPtr
IntPtr.Zero
使用struct:
[StructLayout(LayoutKind.Sequential)] public struct CStruct { //member-list }
并将您的方法声明为:
[DllImport("mydll.dll", OptionName = optionValue, ...)] static extern int DLLFunction(IntPtr cStruct, ...);
在非null情况下,将结构封送至指针并调用该方法:
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CStruct))); try{ Marshal.StructureToPtr(myCStruct, ptr, false); DLLFunction(ptr, ...); } finally { Marshal.FreeHGlobal(ptr); }
在这种null情况下,请使用调用方法IntPtr.Zero:
DLLFunction(IntPtr.Zero, ...);
同样,如果此参数恰好是列表中的最后一个,则可以将其设为可选(或使用包装器将其设置为可选)。通过将其IntPtr cStruct = default(IntPtr)用作参数来执行此操作。(如default(IntPtr) 创建一个IntPtr.Zero。)
IntPtr cStruct = default(IntPtr)
default(IntPtr)
struct在 2)中 使用a 。
只需为非null情况声明一个选项:
[DllImport("mydll.dll", OptionName = optionValue, ...)] static extern int DLLFunction(ref cStruct, ...);
另一种null情况:
传递a时struct,第一个方法将自动被调用,传递时,第二个方法将被自动调用IntPtr.Zero。如果IntPtr使用上面的可选参数声明版本(如 2 的底部所示),则在排除cStruct参数时它将自动调用它。
cStruct
unsafe
使用结构为 2) ,并宣布你的方法(注意unsafe关键字):
[DllImport("mydll.dll", OptionName = optionValue, ...)] static unsafe extern int DLLFunction(CStruct* cStruct, ...);
在非null情况下,您可以通过&myCStruct,并且只需null在null情况下即可。与 1)中一样 ,如果此可选参数为last,则可以将参数声明为排除时CStruct* cStruct = null自动传递。null``cStruct
&myCStruct
CStruct* cStruct = null
null``cStruct
感谢@dialer建议使用此方法。