Nic*_*ick 33 c# parameters null pinvoke ref
我有以下功能:
public static extern uint FILES_GetMemoryMapping(
[MarshalAs(UnmanagedType.LPStr)] string pPathFile,
out ushort Size,
[MarshalAs(UnmanagedType.LPStr)] string MapName,
out ushort PacketSize,
ref Mapping oMapping,
out byte PagesPerSector);
Run Code Online (Sandbox Code Playgroud)
我想这样称呼:
FILES_GetMemoryMapping(MapFile, out size, MapName,
out PacketSize, null, out PagePerSector);
Run Code Online (Sandbox Code Playgroud)
不幸的是,我无法传递null一个需要类型的字段ref Mapping而且没有投射我已经尝试修复此问题.
有什么建议?
Jar*_*Par 32
我假设Mapping是一个结构?如果是这样,您可以使用FILES_GetMemoryMapping()具有不同签名的两个版本的原型.对于要传递的第二个重载,请将null参数设置为an IntPtr并使用IntPtr.Zero
public static extern uint FILES_GetMemoryMapping(
[MarshalAs(UnmanagedType.LPStr)] string pPathFile,
out ushort Size,
[MarshalAs(UnmanagedType.LPStr)] string MapName,
out ushort PacketSize,
IntPtr oMapping,
out byte PagesPerSector);
Run Code Online (Sandbox Code Playgroud)
电话示例:
FILES_GetMemoryMapping(MapFile, out size, MapName,
out PacketSize, IntPtr.Zero, out PagePerSector);
Run Code Online (Sandbox Code Playgroud)
如果Mapping实际上是一个类而不是一个结构,只需将值设置为null,然后再将其传递给它.
And*_*are 31
您无法传递的原因null是因为refC#编译器对参数进行了特殊处理.任何ref参数都必须是可以传递给您正在调用的函数的引用.因为你想传递null编译器是拒绝允许这个,因为你没有提供函数期望的引用.
你唯一真正的选择是创建一个局部变量,将其设置为null,然后传入.编译器不允许你做更多的事情.
虽然@JaredPar的答案无疑是正确的答案,但还有另一个答案:unsafe代码和指针:
unsafe {
Mapping* nullMapping = null;
FILES_GetMemoryMapping(
MapFile,
out size,
MapName,
out PacketSize,
ref *nullMapping, // wat?
out PagePerSector);
}
Run Code Online (Sandbox Code Playgroud)
看起来它应该在运行时失败,但事实并非如此,因为 和ref相互*抵消,并且 的结果值ref *nullMapping是空指针,这就是FILES_GetMemoryMapping()该参数将接收的值。
这可能不是一个好主意,但它是可能的。