Dies ist der zweite Teil der ersten Frage mit c # -Zeigern
So sind Zeiger in c # "unsicher" und werden nicht vom Garbage Collector verwaltet, während IntPtr ein verwaltetes Objekt ist. aber warum Zeiger dann verwenden? und wenn es möglich ist, beide Ansätze synonym zu verwenden?
Die CLI unterscheidet zwischen verwalteten und nicht verwalteten Zeigern. Ein verwalteter Zeiger wird getippt, der Typ des angezeigten Werts ist der Laufzeit bekannt, und nur typsichere Zuweisungen sind zulässig. Nicht verwaltete Zeiger können nur direkt in einer Sprache verwendet werden, die sie unterstützt. C ++ / CLI ist das beste Beispiel.
Das Äquivalent eines nicht verwalteten Zeigers in der C # -Sprache ist IntPtr
. Sie können einen Zeiger mit einem Cast frei hin und her konvertieren. Es ist kein Zeigertyp zugeordnet, obwohl sein Name wie "Zeiger auf int" klingt, es ist das Äquivalent von void*
in C / C ++. Die Verwendung eines solchen Zeigers erfordert pinvoke, die Marshal-Klasse oder eine Umwandlung in einen verwalteten Zeigertyp.
Ein Code zum Spielen:
%Vor% Beachten Sie, wie das unsafe
Schlüsselwort hier angebracht ist. Sie können Marshal.WriteInt64 () anrufen und Sie erhalten keinerlei Beschwerde. Es korrumpiert den Stapelrahmen.
Ein IntPtr
kann nicht als Ersatz für einen Zeiger verwendet werden.
Der IntPtr
enthält nur einen numerischen Wert, sodass Sie ihn nicht für den Zugriff auf Daten verwenden können. Daher der Name; Es ist ein ganzzahliger Wert mit der gleichen Größe wie ein Zeiger. Sie müssen den Wert in einen Zeiger umwandeln, um auf die Daten zugreifen zu können, auf die er zeigt, so dass es keine Möglichkeit gibt, auf die Daten zuzugreifen, ohne unsicheren Code zu verwenden.
Beachten Sie auch, dass IntPtr
eine Struktur und kein Objekt ist, sodass der Garbage Collector nicht direkt betroffen ist.
IntPtr
ist ein verwaltetes Objekt, aber das Objekt, auf das es verweist, ist immer noch kein Garbage Collection. Die Verwendung von unsicheren Zeigern in C # ist wirklich etwas, das Sie vermeiden sollten. Code, der unsichere Zeiger verwendet, berücksichtigt möglicherweise keine Unterschiede in den Speicheradressen zwischen x86- und x64-Systemen. Es ermöglicht Ihnen, Speicheradressen einfach direkt zu bearbeiten, was bei IntPtr nicht der Fall ist, da Sie zwischen dem Zeiger und der tatsächlichen Struktur, die an dieser Speicheradresse gespeichert ist, marshallen müssten. Mit unsicheren Zeigern könnten Sie direkt mit dem zugrunde liegenden Typ arbeiten: hier ist ein Blogbeitrag Ich habe eine mögliche Verwendung unsicherer Zeiger geschrieben. Ein anderes gängiges Beispiel ist die Bearbeitung von Bildpixeln direkt.