pin_ptr (C++/CLI)pin_ptr (C++/CLI)

"固定ポインター" を宣言します。これは共通言語ランタイムでのみ使用されます。Declares a pinning pointer, which is used only with the common language runtime.

すべてのランタイムAll Runtimes

(この言語機能にはランタイムに適用される特記事項がありません。)(There are no remarks for this language feature that apply to all runtimes.)

Windows ランタイムWindows Runtime

(Windows ランタイムでは、この言語機能はサポートされていません。)(This language feature is not supported in the Windows Runtime.)

共通言語ランタイムCommon Language Runtime

"固定ポインター" は、指されているオブジェクトがガベージ コレクション ヒープに移動されないようにする内部ポインターです。A pinning pointer is an interior pointer that prevents the object pointed to from moving on the garbage-collected heap. つまり、固定ポインターの値は、共通言語ランタイムによって変更されることはありません。That is, the value of a pinning pointer is not changed by the common language runtime. これは、マネージド クラスのアドレスをアンマネージド関数に渡すときに、アンマネージド関数呼び出しの解決時にアドレスが予想外に変更されないようにする場合に必要です。This is required when you pass the address of a managed class to an unmanaged function so that the address will not change unexpectedly during resolution of the unmanaged function call.

構文Syntax

[cli::]pin_ptr<cv_qualifiertype>var = &initializer;

パラメーターParameters

cv_qualifiercv_qualifier
const または volatile 修飾子。const or volatile qualifiers. 既定では、固定ポインターは volatile です。By default, a pinning pointer is volatile. 固定ポインターを volatile と宣言することは冗長になりますが、エラーではありません。It is redundant but not an error to declare a pinning pointer volatile.

typetype
initializer の型。The type of initializer.

varvar
pin_ptr 変数の名前。The name of the pin_ptr variable.

initializerinitializer
参照型のメンバー、マネージド配列の要素、またはネイティブ ポインターに割り当てることができるその他のオブジェクト。A member of a reference type, element of a managed array, or any other object that you can assign to a native pointer.

解説Remarks

pin_ptr は、ネイティブ ポインターの機能のスーパーセットを表します。A pin_ptr represents a superset of the functionality of a native pointer. そのため、ネイティブ ポインターに割り当てることができるものは、すべて pin_ptr にも割り当てることができます。Therefore, anything that can be assigned to a native pointer can also be assigned to a pin_ptr. 内部ポインターは、比較演算やポインター演算など、ネイティブ ポインターと同じ一連の操作を実行できます。An interior pointer is permitted to perform the same set of operations as native pointers, including comparison and pointer arithmetic.

マネージド クラスのオブジェクトまたはサブオブジェクトを固定できます。この場合、ガベージ コレクション中に共通言語ランタイムによって移動されることはなくなります。An object or sub-object of a managed class can be pinned, in which case the common language runtime will not move it during garbage collection. これの主な用途は、ポインターをマネージド データに対して、アンマネージド関数呼び出しの実際のポインターとして渡すことです。The principal use of this is to pass a pointer to managed data as an actual parameter of an unmanaged function call. コレクション サイクル中、ランタイムは、固定ポインター用に作成されたメタデータを検査しますが、それが指している項目を移動しません。During a collection cycle, the runtime will inspect the metadata created for the pinning pointer and will not move the item it points to.

オブジェクトを固定すると、その値フィールド (つまり、プリミティブ型または値型のフィールド) も固定されます。Pinning an object also pins its value fields; that is, fields of primitive or value type. ただし、追跡ハンドルによって宣言されたフィールド (%) は固定されません。However, fields declared by tracking handle (%) are not pinned.

マネージド オブジェクトに定義されているサブオブジェクトの固定には、オブジェクト全体を固定するという効果があります。Pinning a sub-object defined in a managed object has the effect of pinning the whole object.

固定ポインターが新しい値のポインターに再割り当てされた場合、それが指していたインスタンスは固定解除されたとみなされます。If the pinning pointer is reassigned to point to a new value, the previous instance pointed to is no longer considered pinned.

オブジェクトは、pin_ptr がそれを指している間のみ固定されます。An object is pinned only while a pin_ptr points to it. 固定ポインターがスコープ外になるか、nullptr が設定されると、オブジェクトは固定解除されます。The object is no longer pinned when its pinning pointer goes out of scope, or is set to nullptr. pin_ptr がスコープ外になった後、固定されていたオブジェクトをガベージ コレクターによってヒープに移動できます。After the pin_ptr goes out of scope, the object that was pinned can be moved in the heap by the garbage collector. まだオブジェクトを指している任意のネイティブ ポインターは更新されません。いずれかを逆参照すると、回復不能な例外が生じる可能性があります。Any native pointers that still point to the object will not be updated, and de-referencing one of them could raise an unrecoverable exception.

オブジェクトを指している固定ポインターがない (すべての固定ポインターがスコープ外になった、他のオブジェクトを指すように再割り当てされた、または nullptr が割り当てられた) 場合、オブジェクトは固定されていないことが保証されます。If no pinning pointers point to the object (all pinning pointers went out of scope, were reassigned to point to other objects, or were assigned nullptr), the object is guaranteed not to be pinned.

固定ポインターは、参照ハンドル、値型またはボックス化された型のハンドル、マネージ型のメンバー、またはマネージド配列の要素を指すことができます。A pinning pointer can point to a reference handle, value type or boxed type handle, member of a managed type, or an element of a managed array. 参照型を指すことはできません。It cannot point to a reference type.

ネイティブ オブジェクトを指している pin_ptr のアドレスを取得すると、未定義の動作が発生します。Taking the address of a pin_ptr that points to a native object causes undefined behavior.

固定ポインターは、スタックの非静的ローカル変数としてのみ宣言できます。Pinning pointers can only be declared as non-static local variables on the stack.

固定ポインターは、以下として使用することはできません。Pinning pointers cannot be used as:

  • 関数パラメーターfunction parameters

  • 関数の戻り値の型the return type of a function

  • クラスのメンバーa member of a class

  • キャストのターゲット型the target type of a cast.

pin_ptr は、cli 名前空間内にあります。pin_ptr is in the cli namespace. 詳細については、「プラットフォーム、既定、および cli 名前空間」を参照してください。For more information, see Platform, default, and cli Namespaces.

内部ポインターの詳細については、「interior_ptr (C++/CLI)」を参照してください。For more information about interior pointers, see interior_ptr (C++/CLI).

固定ポインターの詳細については、方法: ポインターと配列を固定する」と「方法: 固定ポインターと値型を宣言する」を参照してください。For more information about pinning pointers, see How to: Pin Pointers and Arrays and How to: Declare Pinning Pointers and Value Types.

要件Requirements

コンパイラ オプション: /clrCompiler option: /clr

使用例Examples

次の例では、pin_ptr を使用して、配列の最初の要素の位置を制限します。The following example uses pin_ptr to constrain the position of the first element of an array.

// pin_ptr_1.cpp
// compile with: /clr
using namespace System;
#define SIZE 10

#pragma unmanaged
// native function that initializes an array
void native_function(int* p) {
   for(int i = 0 ; i < 10 ; i++)
    p[i] = i;
}
#pragma managed

public ref class A {
private:
   array<int>^ arr;   // CLR integer array

public:
   A() {
      arr = gcnew array<int>(SIZE);
   }

   void load() {
   pin_ptr<int> p = &arr[0];   // pin pointer to first element in arr
   int* np = p;   // pointer to the first element in arr
   native_function(np);   // pass pointer to native function
   }

   int sum() {
      int total = 0;
      for (int i = 0 ; i < SIZE ; i++)
         total += arr[i];
      return total;
   }
};

int main() {
   A^ a = gcnew A;
   a->load();   // initialize managed array using the native function
   Console::WriteLine(a->sum());
}
45

次の例では、内部ポインターを固定ポインターに変換でき、オペランドがマネージド ヒープ上にある場合は address-of 演算子 (&) の戻り値の型が内部ポインターであることを示します。The following example shows that an interior pointer can be converted to a pinning pointer, and that the return type of the address-of operator (&) is an interior pointer when the operand is on the managed heap.

// pin_ptr_2.cpp
// compile with: /clr
using namespace System;

ref struct G {
   G() : i(1) {}
   int i;
};

ref struct H {
   H() : j(2) {}
   int j;
};

int main() {
   G ^ g = gcnew G;   // g is a whole reference object pointer
   H ^ h = gcnew H;

   interior_ptr<int> l = &(g->i);   // l is interior pointer

   pin_ptr<int> k = &(h->j);   // k is a pinning interior pointer

   k = l;   // ok
   Console::WriteLine(*k);
};
1

次の例では、固定ポインターを別の型にキャストできることを示します。The following example shows that a pinning pointer can be cast to another type.

// pin_ptr_3.cpp
// compile with: /clr
using namespace System;

ref class ManagedType {
public:
   int i;
};

int main() {
   ManagedType ^mt = gcnew ManagedType;
   pin_ptr<int> pt = &mt->i;
   *pt = 8;
   Console::WriteLine(mt->i);

   char *pc = ( char* ) pt;
   *pc = 255;
   Console::WriteLine(mt->i);
}
8
255