C#: как передать null функции, ожидающей 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);
который я хотел бы назвать так:
FILES_GetMemoryMapping(MapFile, out size, MapName,
out PacketSize, null, out PagePerSector);
к сожалению, я не могу пройти null
в поле, для которого требуется тип ref Mapping
и никакой бросок я не пробовал исправить это.
какие предложения?
6 ответов
Я предполагаю, что отображение является структурой? Если это так, вы можете иметь две версии FILES_GetMemoryMapping()
прототип с разными сигнатурами. Для второй перегрузки, где вы хотите пройти null
, выберите параметр 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);
вызов пример:
FILES_GetMemoryMapping(MapFile, out size, MapName,
out PacketSize, IntPtr.Zero, out PagePerSector);
если сопоставление на самом деле является классом, а не структурой, просто установите значение null перед его передачей.
причина, по которой вы не можете пройти null
, потому что ref
параметр получает специальную обработку компилятором C#. Любой ref
параметр должен быть ссылкой, которая может быть передана вызываемой функции. Так как вы хотите пройти null
компилятор отказывается разрешить это, так как вы не предоставляете справку о том, что функция ожидает получить.
ваш единственный реальный вариант-создать локальную переменную, установите его в null
, и передать это. Этот компилятор не позволит вам сделать гораздо больше.
Mapping oMapping = null;
FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, ref oMapping, out PagePerSector);
а @JaredPar это ответ несомненно правильно ответ тут другое ответ: unsafe
код и указатели:
unsafe {
Mapping* nullMapping = null;
FILES_GetMemoryMapping(
MapFile,
out size,
MapName,
out PacketSize,
ref *nullMapping, // wat?
out PagePerSector);
}
это выглядит как будто это должно произойти во время выполнения, но это не так, потому что ref
и *
компенсируют друг друга и результирующее значение ref *nullMapping
является нулевым указателем, который является то, что FILES_GetMemoryMapping()
получит для этого параметра.
это, вероятно, не хорошая идея!--10-->, но это возможно.
возможно, это не совсем идеальный ответ, но если вам нужно передать null в качестве параметра при вызове функции, подумайте о перегрузке этой функции, которая опускает формальный параметр для переменной, которую вы пытаетесь установить в null.
например, скажем, у вас есть функция, которая выглядит так:
public void MyFunction(string x, int y, ref string z) {...};
вы хотите иметь возможность передавать null для параметра z. Попробуйте вместо этого создать новый MyFunction
перегрузка, которая выглядит примерно так это:
public void MyFunction(string x, int y) {...};
этот подход не будет соответствовать потребностям каждого, но это еще одно возможное решение.