43

我有以下功能:

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);

我想这样称呼:

FILES_GetMemoryMapping(MapFile, out size, MapName,
    out PacketSize, null, out PagePerSector);

不幸的是,我无法传入null需要类型的字段,ref Mapping并且我尝试过没有强制转换来解决此问题。

有什么建议么?

4

7 回答 7

42

无法传递null的原因ref是 C# 编译器对参数进行了特殊处理。任何ref参数都必须是可以传递给您正在调用的函数的引用。由于您要通过null编译器,因此拒绝允许这样做,因为您没有提供函数期望的引用。

您唯一真正的选择是创建一个局部变量,将其设置为null,然后将其传入。编译器将不允许您做更多的事情。

于 2009-04-10T01:52:07.633 回答
32

我假设 Mapping 是一个结构?如果是这样,您可以拥有FILES_GetMemoryMapping()具有不同签名的两个版本的原型。对于要传递的第二个重载,null将参数设为 anIntPtr并使用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);

调用示例:

FILES_GetMemoryMapping(MapFile, out size, MapName,
   out PacketSize, IntPtr.Zero, out PagePerSector);

如果 Mapping 实际上是一个类而不是结构,只需在传递之前将值设置为 null。

于 2009-04-10T01:51:20.300 回答
11

一种方法是创建一个虚拟变量,将其赋值为 null,然后将其传入。

于 2009-04-10T01:50:50.990 回答
4
Mapping oMapping = null;

FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, ref oMapping, out PagePerSector);
于 2009-04-10T01:50:57.243 回答
4

虽然@JaredPar 的答案无疑是正确答案,但还有另一个答案:unsafe代码和指针:

unsafe {
    Mapping* nullMapping = null;
    FILES_GetMemoryMapping(
            MapFile,
            out size,
            MapName,
            out PacketSize,
            ref *nullMapping,    // wat?
            out PagePerSector);
}

看起来它应该在运行时失败,但事实并非如此,因为ref*相互抵消,结果值ref *nullMapping是空指针,这是FILES_GetMemoryMapping()该参数将接收的值。

这可能不是一个好主意,但有可能

于 2015-10-22T14:43:31.037 回答
2

现在可以使用 C# 语言 7.2 或更高版本允许 Null。只需像这样替换ref函数参数中的...

void MyFunc(ref Object obj) { ... }

到...

void MyFunc(in Object obj) { ... }

这将允许您null在应用程序中调用函数时作为参数值传入。它对对象和本机类型的工作方式相同,并且在语法上等同于ref readonly.

于 2019-06-07T18:01:16.377 回答
0

也许它不完全是理想的答案,但如果您需要在调用函数时将 null 作为参数传递,请考虑对该函数进行重载,以省略您尝试设置为 null 的变量的形参。

例如,假设您有一个如下所示的函数:

public void MyFunction(string x, int y, ref string z) {...};

您希望能够为参数 z 传递 null。尝试创建一个MyFunction看起来像这样的新重载:

public void MyFunction(string x, int y) {...};

这种方法并不适合每个人的需求,但它是另一种可能的解决方案。

于 2018-06-22T04:30:27.053 回答