Irgendeine reale Verwendung von Zeigern in C #? [geschlossen]


19

Was ist eine Situation beim Codieren in C #, in der die Verwendung von Zeigern eine gute oder notwendige Option ist? Ich spreche von unsicheren Zeigern.


8
Ahhh Mann, ich habe die Frage gesehen und war sehr glücklich, weil ich erklären musste, dass Sie in C # die ganze Zeit Zeiger verwenden, dies aber ruinieren mussten, indem Sie das unsichere Schlüsselwort explizit ausdrücken. Mist! :)
Tony

Antworten:


25

Vom Entwickler von C # selbst:

Die Verwendung von Zeigern ist in C # selten erforderlich, es gibt jedoch Situationen, in denen dies erforderlich ist. Die Verwendung eines unsicheren Kontexts zum Zulassen von Zeigern ist beispielsweise in den folgenden Fällen gerechtfertigt:

  • Umgang mit vorhandenen Strukturen auf der Festplatte
  • Erweiterte COM- oder Platform-Invoke-Szenarien, in denen Strukturen mit Zeigern enthalten sind
  • Leistungskritischer Code

Von der Verwendung von unsicherem Kontext in anderen Situationen wird abgeraten.

Insbesondere sollte kein unsicherer Kontext verwendet werden, um zu versuchen, C-Code in C # zu schreiben.

Achtung: "Code, der mit einem unsicheren Kontext geschrieben wurde, kann nicht als sicher überprüft werden. Daher wird er nur ausgeführt, wenn der Code vollständig vertrauenswürdig ist. Mit anderen Worten, unsicherer Code kann in einer nicht vertrauenswürdigen Umgebung nicht ausgeführt werden. Beispielsweise können Sie unsicher nicht ausführen Code direkt aus dem Internet. "

Sie können dies als Referenz durchgehen


"Unsicherer Code kann in einer nicht vertrauenswürdigen Umgebung nicht ausgeführt werden." Meinten Sie "trusted"?
Don Larynx

18

Ja, es gibt echte Anwendungen, wenn die Leistung kritisch ist und die Vorgänge auf niedrigem Niveau sind

Zum Beispiel musste ich Zeiger in C # nur einmal für den Bildvergleich verwenden. Die Verwendung von GetPixel für ein Paar von 1024 x 1024 x 32-Bildern dauerte 2 Minuten, um den Vergleich durchzuführen (genaue Übereinstimmung). Das Fixieren des Bildspeichers und das Verwenden von Zeigern dauerte weniger als 1 Sekunde (auf demselben Computer natürlich).


2
Ich habe Sie LockBits dafür verwendet ... ( msdn.microsoft.com/en-us/library/… )
Konfigurator

1
@configurator: das war .net 2, LockBits existierte nicht
Steven A. Lowe

2
Klar gab es das schon seit 1.0 ...
Konfigurator

@configurator: Mein Fehler, ich war verwirrt beim Navigieren in der MSDN-Dokumentation (als ich zu .net 2 in der Droplist wechselte, ging es zu einer völlig anderen Seite, auf der keine Lockbits erwähnt wurden). Ja, so steckt man den Bildspeicher fest.
Steven A. Lowe

6

Sie müssen sich daran erinnern, dass die Designer bei Microsoft clevere Leute sind und alles, was sie zu C # hinzufügen, mindestens einen Anwendungsfall hat. Das FParsec-Projekt verwendet unsicheren Code, um den letzten Leistungsabfall zu erzielen, zu dem C # in der Lage ist. Beachten Sie die Verwendung von fixedund 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
Ich würde sagen, die Entwickler (bei Microsoft oder einem anderen Unternehmen) wären ein Idiot, wenn sie eine Funktion enthalten würden, da es einen Anwendungsfall gibt. Ein Feature sollte viel mehr als nur einen Anwendungsfall haben. sonst ist es ein aufblähen.
Lie Ryan

4
Raymond Chen hat oft gesagt, dass Features bei Microsoft bei -100 "Punkten" beginnen. Damit ein Feature implementiert werden kann, muss es "einen signifikanten positiven Nettoeffekt auf das Gesamtpaket haben, damit es eingebunden werden kann". Hier ist ericgus Blogpost zu diesem Jahr: blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx
Jesse Buchanan

Ich bin mir ziemlich sicher, dass einige String-Operationen intern unsicheren Code verwenden. Daher war FParsec möglicherweise nicht die Priorität.
Arturo Torres Sánchez

4

Ich musste einmal Zeiger (im unsicheren Kontext) in einer C # -basierten Windows-Anwendung verwenden, die als Schnittstelle zu einem Headset fungieren würde. Diese Anwendung ist eine Benutzeroberfläche, über die Agenten (in einem Callcenter) ihre Kopfhörereinstellungen steuern können. Diese Anwendung fungiert als Alternative zum Bedienfeld des Headset-Herstellers. Daher war ihre Fähigkeit zur Steuerung der Headsets im Vergleich zu den verfügbaren Optionen eingeschränkt. Ich musste Zeiger verwenden, da ich die API (eine Visual C ++ - DLL) verwenden musste, die vom Hersteller des Headsets mithilfe von P / Invoke bereitgestellt wurde.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.