Qualche uso reale dei puntatori in C #? [chiuso]


19

Qual è una situazione durante la codifica in C # in cui l'utilizzo dei puntatori è un'opzione valida o necessaria? Sto parlando di puntatori non sicuri .


8
Ahhh amico, ho visto la domanda e sono diventato tutto contento perché avrei spiegato che in C # usi sempre i puntatori ma dovevi andare a rovinarlo dicendo esplicitamente la parola chiave non sicura. Dang it! :)
Tony,

Risposte:


25

Dallo stesso sviluppatore di C #:

L'uso di puntatori è raramente richiesto in C #, ma ci sono alcune situazioni che li richiedono. Ad esempio, l'utilizzo di un contesto non sicuro per consentire i puntatori è garantito dai seguenti casi:

  • Gestire strutture esistenti su disco
  • COM o piattaforma avanzata Richiama scenari che coinvolgono strutture con puntatori al loro interno
  • Codice critico per le prestazioni

L'uso del contesto non sicuro in altre situazioni è scoraggiato.

In particolare, un contesto non sicuro non deve essere utilizzato per tentare di scrivere codice C in C #.

Attenzione: "Il codice scritto utilizzando un contesto non sicuro non può essere verificato come sicuro, quindi verrà eseguito solo quando il codice è completamente affidabile. In altre parole, il codice non sicuro non può essere eseguito in un ambiente non attendibile. Ad esempio, non è possibile eseguire non sicuri codice direttamente da Internet. "

Si può passare attraverso questo per riferimento


"il codice non sicuro non può essere eseguito in un ambiente non attendibile." Intendevi "fidato"?
Don Larynx,

18

sì, ci sono usi reali, quando le prestazioni sono fondamentali e le operazioni sono di basso livello

per esempio, ho solo bisogno di usare i puntatori in C # una volta, per il confronto delle immagini. L'utilizzo di GetPixel su una coppia di immagini 1024x1024x32 ha richiesto 2 minuti per eseguire il confronto (corrispondenza esatta). Il blocco della memoria delle immagini e l'utilizzo dei puntatori ha richiesto meno di 1 secondo (ovviamente sulla stessa macchina).


2
Ho usato LockBits per questo ... ( msdn.microsoft.com/en-us/library/… )
configuratore

1
@configurator: questo era .net 2, LockBits non esisteva
Steven A. Lowe

2
Certo, esisteva dall'1.0 ...
configuratore

@configurator: errore mio, mi sono confuso navigando nella documentazione MSDN (quando sono passato a .net 2 nella lista a discesa è andato a una pagina completamente diversa che non menzionava i lockbit). Sì, è così che si blocca la memoria dell'immagine.
Steven A. Lowe,

6

Devi ricordare che i designer di Microsoft sono persone intelligenti e tutto ciò che aggiungono a C # ha almeno 1 caso d'uso. Il progetto FParsec utilizza un codice non sicuro per far emergere ogni goccia di prestazioni di cui C # è capace. Prendi nota dell'uso di fixede 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;
        }
    }
}

1
Direi che gli sviluppatori (di Microsoft o di altre società) sarebbero un idiota se includessero alcune funzionalità perché ha 1 caso d'uso. Una funzione dovrebbe avere molto più di 1 solo caso d'uso; altrimenti è gonfio.
Lie Ryan,

4
Raymond Chen ha spesso affermato che le funzionalità di Microsoft partono da -100 "punti". Per poter implementare una funzione, "deve avere un significativo effetto netto positivo sul pacchetto complessivo affinché possa essere inclusa". Ecco il post sul blog di ericgu su questo c.2004: blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx
Jesse Buchanan,

Sono abbastanza sicuro che alcune operazioni String utilizzino internamente un codice non sicuro. Pertanto, FParsec potrebbe non essere stata la priorità.
Arturo Torres Sánchez,

4

Una volta ho dovuto usare i puntatori (nel contesto non sicuro) in un'applicazione Windows basata su C # che fungesse da interfaccia per un auricolare. Questa applicazione è un'interfaccia utente che consentirebbe agli agenti (in un call center) di controllare le impostazioni delle cuffie. Questa applicazione funge da alternativa al pannello di controllo fornito dal produttore dell'auricolare. Pertanto, la loro capacità di controllare le cuffie era limitata rispetto alle opzioni disponibili. Ho dovuto usare i puntatori perché dovevo usare l'API (una DLL Visual C ++) fornita dal produttore delle cuffie usando P / Invoke.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.