Wednesday, April 20, 2011

C#: How to pass null to a function expecting a ref?

I've got the following function:

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

Which I would like to call like this:

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

Unfortunately, I cannot pass "null" in a field that requires type "ref Mapping" and no cast I've tried fixes this?

Any suggestions?

From stackoverflow
  • One way is to create a dummy variable, assign it null, and pass that in.

  • Mapping oMapping = null;
    
    FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, ref oMapping, out PagePerSector);
    
    Nick : Mapping is actually a struct so I cannot set it to null.
    JaredPar : @Nick, see my answer for the structure case
    Spencer Ruport : I think this misses the point. Sometimes functions have ref parameters that you don't care about. Having to define useless variables clutters code and is annoying.
  • I'm assuming that Mapping is a structure? If so you can have two versions of the FILES_GetMemoryMapping prototype with different signatures. For the second overload where you want to pass null, make the parameter an IntPtr and use 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);
    

    Call Example:

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

    If Mapping is actually a class instead of a structure, just set the value to null before passing it down.

    Nick : Works like a charm!
    Calmarius : And what do you suggest if you have a function with 8 pointer to structs and any of them can be null? Should I write 256 overloads? Using nullable value type will dummy variable works?
  • The reason you cannot pass null is because a ref parameter is given special treatment by the C# compiler. Any ref parameter must be a reference that can be passed to the function you are calling. Since you want to pass null the compiler is refusing to allow this since you are not providing a reference that the function is expecting to have.

    Your only real option would be to create a local variable, set it to null, and pass that in. The compiler will not allow you to do much more than that.

  • @Calmarius, if you have many parameters which allow null values, it may be better to redefine the structs as classes. That way, you'll be able to write your import declaration without any ref modifiers and pass null for any of the parameters when you invoke it.

0 comments:

Post a Comment