Toute utilisation réelle de pointeurs en C #? [fermé]

19

Quelle est une situation lors du codage en C # où l'utilisation de pointeurs est une bonne ou nécessaire option? Je parle de pointeurs dangereux .

Gulshan
la source
8
Ahhh mec, j'ai vu la question et je suis devenu tout heureux parce que je pourrais expliquer qu'en C # vous utilisez des pointeurs tout le temps mais vous avez dû aller le gâcher en disant explicitement le mot-clé dangereux. Dang it! :)
Tony

Réponses:

25

Du développeur de C # lui-même:

L'utilisation de pointeurs est rarement requise en C #, mais il existe certaines situations qui les nécessitent. Par exemple, l'utilisation d'un contexte non sécurisé pour autoriser les pointeurs est garantie par les cas suivants:

  • Gestion des structures existantes sur disque
  • Scénarios avancés d'invocation de COM ou de plate-forme impliquant des structures contenant des pointeurs
  • Code critique pour les performances

L'utilisation d'un contexte dangereux dans d'autres situations est déconseillée.

Plus précisément, un contexte dangereux ne doit pas être utilisé pour tenter d'écrire du code C en C #.

Attention: "Le code écrit à l'aide d'un contexte non sécurisé ne peut pas être vérifié pour être sûr, il ne sera donc exécuté que lorsque le code est entièrement fiable. En d'autres termes, le code non sécurisé ne peut pas être exécuté dans un environnement non approuvé. Par exemple, vous ne pouvez pas exécuter un programme non sécurisé directement depuis Internet. "

Vous pouvez parcourir cela pour référence

ykombinator
la source
"Le code dangereux ne peut pas être exécuté dans un environnement non fiable." Voulez-vous dire "de confiance"?
Don Larynx
18

oui, il y a de réelles utilisations, lorsque les performances sont critiques et que les opérations sont de bas niveau

par exemple, je n'ai eu besoin d'utiliser les pointeurs en C # qu'une seule fois, pour la comparaison d'images. L'utilisation de GetPixel sur une paire d'images 1024x1024x32 a pris 2 minutes pour faire la comparaison (correspondance exacte). L'épinglage de la mémoire d'image et l'utilisation de pointeurs ont pris moins d'une seconde (sur la même machine bien sûr).

Steven A. Lowe
la source
2
Je vous ai utilisé LockBits pour cela ... ( msdn.microsoft.com/en-us/library/… )
configurateur
1
@configurator: c'était .net 2, LockBits n'existait pas
Steven A. Lowe
2
Bien sûr, il existait depuis 1.0 ...
configurateur
@configurator: mon erreur, je me suis trompé en naviguant dans la documentation MSDN (lorsque je suis passé à .net 2 dans la liste déroulante, il est allé sur une page complètement différente qui ne mentionnait pas les bits de verrouillage). Oui, c'est ainsi que vous épinglez la mémoire d'image.
Steven A. Lowe
6

Vous devez vous rappeler que les concepteurs de Microsoft sont des gens intelligents et tout ce qu'ils ajoutent à C # a au moins 1 cas d'utilisation. Le projet FParsec utilise du code dangereux pour faire ressortir chaque dernière baisse de performances dont C # est capable. Prenez note de l'utilisation de fixedet stackalloc.

private char* ReadCharsFromStream(char* buffer, int maxCount, out string overhangChars) {
    Debug.Assert(maxCount >= 0);
    fixed (byte* byteBuffer = ByteBuffer) {
        overhangChars = null;
        try {
            while (maxCount >= MaxCharCountForOneByte) {// if maxCount < MaxCharCountForOneByte, Convert could throw
                int nBytesInByteBuffer = FillByteBuffer();
                bool flush = nBytesInByteBuffer == 0;
                int bytesUsed, charsUsed; bool completed = false;
                Decoder.Convert(byteBuffer + ByteBufferIndex, nBytesInByteBuffer,
                                buffer, maxCount, flush,
                                out bytesUsed, out charsUsed, out completed);
                ByteBufferIndex += bytesUsed; // GetChars consumed bytesUsed bytes from the byte buffer
                buffer += charsUsed;
                maxCount -= charsUsed;
                if (flush && completed) return buffer;
            }
            if (maxCount == 0) return buffer;

            char* cs = stackalloc char[MaxCharCountForOneByte];
            for (;;) {
                int nBytesInByteBuffer = FillByteBuffer();
                bool flush = nBytesInByteBuffer == 0;
                int bytesUsed, charsUsed; bool completed;
                Decoder.Convert(byteBuffer + ByteBufferIndex, nBytesInByteBuffer,
                                cs, MaxCharCountForOneByte, flush,
                                out bytesUsed, out charsUsed, out completed);
                ByteBufferIndex += bytesUsed;
                if (charsUsed > 0) {
                    int i = 0;
                    do {
                        *(buffer++) = cs[i++];
                        if (--maxCount == 0) {
                            if (i < charsUsed) overhangChars = new string(cs, i, charsUsed - i);
                            return buffer;
                        }
                    } while (i < charsUsed);
                }
                if (flush && completed) return buffer;
            }
        } catch (DecoderFallbackException e) {
            e.Data.Add("Stream.Position", ByteIndex + e.Index);
            throw;
        }
    }
}
ChaosPandion
la source
1
Je dirais que les développeurs (chez Microsoft ou dans toute autre entreprise) seraient idiots s'ils incluaient une fonctionnalité, car elle a 1 cas d'utilisation. Une fonctionnalité doit avoir bien plus que 1 cas d'utilisation; sinon c'est un ballonnement.
Lie Ryan
4
Raymond Chen a souvent dit que les fonctionnalités de Microsoft commencent à -100 "points". Pour qu'une fonctionnalité soit mise en œuvre, elle "doit avoir un effet positif net significatif sur l'ensemble du package pour qu'elle puisse être intégrée". Voici le billet de blog d'ericgu sur ce c.2004: blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx
Jesse Buchanan
Je suis sûr que certaines opérations String utilisent en interne du code non sécurisé. Donc, FParsec n'était peut-être pas la priorité.
Arturo Torres Sánchez
4

Une fois, j'ai dû utiliser des pointeurs (dans le contexte dangereux) dans une application Windows basée sur C # qui ferait office d'interface avec un casque. Cette application est une interface utilisateur qui permettrait aux agents (dans un centre d'appels) de contrôler les paramètres de leurs écouteurs. Cette application agit comme une alternative au panneau de contrôle fourni par le fabricant du casque. Ainsi, leur capacité à contrôler les casques était limitée par rapport aux options disponibles. J'ai dû utiliser des pointeurs parce que je devais utiliser l'API (une DLL Visual C ++) fournie par le fabricant du casque à l'aide de P / Invoke.

k25
la source