183

IntelliSenseを使用し、他の人のコードを調べることで、このIntPtrタイプに出くわしました。それを使用する必要があるたびに、私は単に置くnullIntPtr.Zero、ほとんどの機能が機能することを発見しました。それは正確には何であり、いつ/なぜそれが使用されるのですか?

4

8 に答える 8

170

これは「ネイティブ(プラットフォーム固有)サイズの整数」です。内部的にvoid*は整数として表されますが、公開されます。アンマネージポインタを格納する必要があり、コードを使用したくない場合はいつでも使用できunsafeます。IntPtr.Zero事実上NULL(nullポインタ)です。

于 2009-07-18T18:15:06.053 に答える
73

これは、ネイティブコードまたは安全でないコードで使用されるメモリアドレスを格納するのに十分な大きさの値型ですが、安全なマネージコードでメモリアドレスとして直接使用することはできません。

IntPtr.Size32ビットプロセスと64ビットプロセスのどちらで実行しているかを確認するために使用できます。それぞれ4バイトまたは8バイトになります。

于 2009-07-18T18:15:41.793 に答える
54

次に例を示します。

高速度カメラと連携する C# プログラムを作成しています。カメラには、画像を取得してコンピュータのメモリに自動的にロードする独自のドライバがあります。

したがって、最新の画像をプログラムに取り込んで作業する準備ができたら、カメラドライバーは、画像が物理メモリに既に保存されている場所への IntPtr を提供するので、別の画像を作成するために時間/リソースを無駄にする必要はありません。すでにメモリにある画像を保存するためのメモリのブロック。IntPtr は、画像が既にどこにあるかを示しています。

于 2009-07-18T19:24:36.973 に答える
43

直接解釈

IntPtrは、ポインタと同じサイズの整数です

IntPtrを使用して、ポインター値を非ポインター型に保管できます。ポインタの使用はエラーが発生しやすく、ほとんどのコンテキストで違法であるため、この機能は.NETでは重要です。ポインタ値を「安全な」データ型に格納できるようにすることで、安全でないコードセグメント間の配管を、より安全な高水準コードで、またはポインタを直接サポートしない.NET言語で実装できます。

IntPtrのサイズはプラットフォーム固有ですが、システムが自動的に正しいサイズを使用するため、この詳細を考慮する必要はほとんどありません。

「IntPtr」という名前は紛らわしいです-のようなものHandleがより適切だったかもしれません。私の最初の推測では、「IntPtr」は整数へのポインタでした。IntPtrのMSDNドキュメントは、名前の意味について多くの洞察を提供することなく、やや不可解な詳細になります。

別の視点

AnIntPtrは、2つの制限があるポインタです。

  1. 直接逆参照することはできません
  2. 指しているデータの種類はわかりません。

言い換えると、anIntPtrは-と同じですvoid*が、基本的なポインタ演算に使用できる(ただし使用すべきではない)という追加機能があります。

を逆参照するIntPtrには、それを真のポインター(「安全でない」コンテキストでのみ実行できる操作)にキャストするか、InteropServices.Marshalクラスによって提供されるようなヘルパールーチンに渡すことができます。クラスを使用するMarshalと、明示的な「安全でない」コンテキストにいる必要がないため、安全性の錯覚が生じます。ただし、ポインタの使用に固有のクラッシュのリスクを取り除くことはできません。

于 2009-11-01T01:47:34.547 に答える
22

ポインタとは?

すべての言語で、ポインターはメモリアドレスを格納する変数の一種であり、ポインターが指しているアドレスまたはポインターが指しているアドレスの教えてもらうことができます。

ポインターは一種のブックマークと考えることができます。ただし、本のページにすばやくジャンプするために使用される代わりに、ポインターはメモリのブロックを追跡またはマップするために使用されます。

プログラムのメモリが 65535 バイトの 1 つの大きな配列のように正確に想像できます。

ポインターは素直に指す

ポインターはそれぞれ 1 つのメモリ アドレスを記憶するため、それぞれがメモリ内の 1 つのアドレスを指します。

グループとして、ポインターはメモリアドレスを記憶および呼び出し、すべてのコマンドとうんざりに従います。

あなたは彼らの王です。

C# のポインター

具体的には C# では、ポインタは 0 ~ 65534 のメモリ アドレスを格納する整数変数です。

また、C# 固有のポインターは int 型であるため、符号付きです。

ただし、負の番号のアドレスは使用できず、65534 を超えるアドレスにアクセスすることもできません。アクセスしようとすると、System.AccessViolationException がスローされます。

MyPointerというポインターは、次のように宣言されます。

int *MyPointer;

C# のポインターは int ですが、C# のメモリ アドレスは 0 から始まり、65534 まで拡張されます。

とがったものは特別な注意を払って処理する必要があります

安全ではないという言葉は、あなたを怖がらせることを目的としていますが、それには非常に正当な理由があります。ポインターは尖ったものであり、剣、斧、ポインターなどの尖ったものは特別な注意を払って取り扱う必要があります。

ポインターを使用すると、プログラマーはシステムを厳密に制御できます。したがって、犯した間違いは、より深刻な結果をもたらす可能性があります。

ポインターを使用するには、プログラムのプロパティで安全でないコードを有効にする必要があり、安全でないとマークされたメソッドまたはブロックでのみポインターを使用する必要があります。

安全でないブロックの例

unsafe
{
    // Place code carefully and responsibly here.

}

ポインタの使い方

変数またはオブジェクトが宣言またはインスタンス化されると、それらはメモリに格納されます。

  • * 記号プレフィックスを使用してポインターを宣言します。

int *MyPointer;

  • 変数のアドレスを取得するには、& 記号のプレフィックスを使用します。

MyPointer = &MyVariable;

アドレスがポインターに割り当てられると、次のことが適用されます。

  • int として指されているメモリアドレスを参照するための * 接頭辞なし。

MyPointer = &MyVariable; // Set MyPointer to point at MyVariable

  • * プレフィックスを使用して、ポイントされているメモリ アドレスに格納されている値を取得します。

"MyPointer is pointing at " + *MyPointer;

ポインタはメモリアドレスを保持する変数なので、このメモリアドレスをポインタ変数に格納することができます。

慎重かつ責任を持って使用されているポインターの例

    public unsafe void PointerTest()
    {
        int x = 100; // Create a variable named x

        int *MyPointer = &x; // Store the address of variable named x into the pointer named MyPointer

        textBox1.Text = ((int)MyPointer).ToString(); // Displays the memory address stored in pointer named MyPointer

        textBox2.Text = (*MyPointer).ToString(); // Displays the value of the variable named x via the pointer named MyPointer.

    }

ポインターの型が int であることに注意してください。これは、C# がメモリ アドレスを整数 (int) として解釈するためです。

uintではなくintなのはなぜですか?

正当な理由はありません。

ポインターを使用する理由

ポインタはとても楽しいです。コンピューターの大部分がメモリによって制御されているため、ポインターを使用すると、プログラマーはプログラムのメモリをより詳細に制御できます。

メモリ監視。

ポインタを使用してメモリのブロックを読み取り、ポイントされている値が時間の経過とともにどのように変化するかを監視します。

これらの値を責任を持って変更し、変更がコンピューターに与える影響を追跡してください。

于 2016-09-13T09:28:18.770 に答える
7

MSDNによると:

IntPtrタイプは、サイズがプラットフォーム固有の整数になるように設計されています。つまり、このタイプのインスタンスは、32ビットハードウェアとオペレーティングシステムでは32ビット、64ビットハードウェアとオペレーティングシステムでは64ビットであると予想されます。

IntPtr型は、ポインターをサポートする言語で使用でき、ポインターをサポートする言語とサポートしない言語間でデータを参照する一般的な手段として使用できます。

IntPtrオブジェクトは、ハンドルを保持するためにも使用できます。たとえば、IntPtrのインスタンスは、ファイルハンドルを保持するためにSystem.IO.FileStreamクラスで広く使用されています。

IntPtrタイプはCLSに準拠していますが、UIntPtrタイプは準拠していません。共通言語ランタイムでは、IntPtrタイプのみが使用されます。UIntPtrタイプは、主にIntPtrタイプとのアーキテクチャの対称性を維持するために提供されます。

http://msdn.microsoft.com/en-us/library/system.intptr(VS.71).aspx

于 2009-07-18T18:15:44.383 に答える
5

さて、これはを扱っているMSDNページIntPtrです。

最初の行は次のとおりです。

ポインターまたはハンドルを表すために使用されるプラットフォーム固有のタイプ。

ポインタまたはハンドルが何であるかについては、ページは次のようになります。

IntPtr型は、ポインターをサポートする言語で使用でき、ポインターをサポートする言語とサポートしない言語間でデータを参照する一般的な手段として使用できます。

IntPtrオブジェクトは、ハンドルを保持するためにも使用できます。たとえば、IntPtrのインスタンスは、ファイルハンドルを保持するためにSystem.IO.FileStreamクラスで広く使用されています。

ポインタは、関心のあるデータを保持するメモリ領域への参照です。

ハンドルはオブジェクトの識別子にすることができ、両側がそのオブジェクトにアクセスする必要があるときにメソッド/クラス間で渡されます。

于 2009-07-18T18:14:56.350 に答える
2

AnIntPtrは、主にメモリ アドレスまたはハンドルを保持するために使用される値型です。ポインタはメモリアドレスです。ポインターは、型付き (例: int*) または型なし (例: ) にすることができますvoid*Windows ハンドルは、通常、メモリ アドレスと同じサイズ (またはそれより小さい) の値であり、システム リソース (ファイルやウィンドウなど) を表します。

于 2019-01-13T16:01:19.947 に答える