C#: Comment passer null à une fonction en attendant un ref?

j'ai la fonction suivante:

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 je voudrais appeler comme ceci:

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

Malheureusement, je ne peux pas passer null dans un champ de type ref Mapping et pas de plâtre j'ai essayé de corriger cela.

des suggestions?

28
demandé sur sharptooth 2009-04-10 05:48:34

6 réponses

je suppose que la cartographie est une structure? Si oui, vous pouvez avoir deux versions de l' FILES_GetMemoryMapping() prototype avec différentes signatures. Pour la deuxième surcharge où vous souhaitez passer null, rendre le paramètre IntPtr et utiliser 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);

exemple:

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

si Mapping est en fait une classe au lieu d'une structure, il suffit de définir la valeur à null avant de la passer.

30
répondu JaredPar 2013-09-24 07:43:00

La raison pour laquelle vous ne passerez null est parce que a reçoit un traitement spécial par le compilateur C#. ref paramètre doit être une référence qui peut être passée à la fonction que vous appelez. Puisque vous voulez passer null le compilateur refuse de le permettre puisque vous ne fournissez pas une référence que la fonction attend d'avoir.

Votre seule option serait de créer une variable locale, définie par null, et le passer en. Le compilateur ne vous permettra pas de faire beaucoup plus que cela.

25
répondu Andrew Hare 2009-04-10 01:52:07

une façon est de créer une variable fictive, de l'attribuer à null, et de la passer.

9
répondu Erich Mirabal 2009-04-10 01:50:50
Mapping oMapping = null;

FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, ref oMapping, out PagePerSector);
4
répondu Chris Doggett 2009-04-10 01:50:57

alors que @Jaredpar's réponse est sans doute le correct réponse,un autre réponse: unsafe code et pointeurs:

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

regarde comme il devrait échouer à l'exécution, mais il ne le fait pas, parce que le ref et * annuler l'un l'autre, et la valeur résultante de ref *nullMapping est le pointeur nul, ce qui est ce que FILES_GetMemoryMapping() recevrez pour ce paramètre.

Ce n'est probablement pas un bonne idée possible.

1
répondu jonp 2017-05-23 12:26:20

peut-être que ce n'est pas exactement la réponse idéale, mais si vous devez passer null comme paramètre lors de l'appel d'une fonction, envisagez de faire une surcharge de cette fonction qui omet le paramètre formel pour la variable que vous essayez de définir à null.

Par exemple, disons que vous avez une fonction qui ressemble à ceci:

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

vous voulez pouvoir passer null pour le paramètre z. Essayez plutôt de créer un nouveau MyFunction surcharge qui ressemble à quelque chose comme ceci:

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

cette approche ne conviendra pas aux besoins de tout le monde, mais c'est une autre solution possible.

0
répondu Jazimov 2018-06-22 04:30:27