valores valor utilizadas utilice tipo tener significa que puede palabras objeto net debe dato convertir codigos acepte acepta c# null pinvoke parameters ref

valor - que significa c#



C#: ¿Cómo pasar nulo a una función que espera una referencia? (6)

Tengo la siguiente función:

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

Que me gustaría llamar así:

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

Desafortunadamente, no puedo pasar el null en un campo que requiere ref Mapping tipo y no se ha intentado corregir este problema.

¿Alguna sugerencia?


Estoy asumiendo que el Mapeo es una estructura? Si es así, puedes tener dos versiones del prototipo FILES_GetMemoryMapping() con diferentes firmas. Para la segunda sobrecarga en la que desea pasar null , haga que el parámetro sea IntPtr y 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);

Ejemplo de llamada:

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

Si la asignación es en realidad una clase en lugar de una estructura, simplemente establezca el valor en nulo antes de pasarlo.


La razón por la que no puede pasar null es porque el compilador de C # le da un tratamiento especial a un parámetro ref . Cualquier parámetro de ref debe ser una referencia que se pueda pasar a la función que está llamando. Como quiere pasar null el compilador se niega a permitir esto ya que no está proporcionando una referencia que la función espera tener.

Su única opción real sería crear una variable local, establecerla en null y pasarla. El compilador no le permitirá hacer mucho más que eso.


Quizás no sea exactamente la respuesta ideal, pero si necesita pasar nulo como parámetro al llamar a una función, considere hacer una sobrecarga de esa función que omita el parámetro formal para la variable que está tratando de establecer como nula.

Por ejemplo, digamos que tiene una función que se parece a esto:

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

Desea poder pasar nulo para el parámetro z. En su lugar, intente crear una nueva sobrecarga de MyFunction que se parezca a esto:

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

Este enfoque no se adaptará a las necesidades de todos, pero es otra solución posible.


Si bien la answer @ JaredPar es sin duda la respuesta correcta , hay otra respuesta: código unsafe y punteros:

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

Parece que debería fallar en el tiempo de ejecución, pero no lo hace, porque la ref y la * cancelan mutuamente, y el valor resultante de ref *nullMapping es el puntero nulo, que es lo que FILES_GetMemoryMapping() recibirá para ese parámetro .

Probablemente no sea una buena idea , pero es posible .


Una forma es crear una variable ficticia, asignarla nula y pasarla.


Mapping oMapping = null; FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, ref oMapping, out PagePerSector);