Condividi tramite


pin_ptr (C++/CLI)

Dichiara un puntatore di blocco, utilizzato solo con Common Language Runtime.

Tutti i runtime

(Non esistono commenti della funzionalità del linguaggio che si applicano a tutti i runtime.)

Finestre runtime

(Questa funzionalità del linguaggio non è supportata nelle finestre runtime).

Common Language Runtime

Un puntatore di blocco è un puntatore interno che estende l'oggetto fa riferimento a spostamento nell'heap sottoposto a garbage collection.Ovvero il valore di un puntatore di blocco non viene modificato da Common Language Runtime.Questa condizione è obbligatoria quando si passa l'indirizzo di una classe gestita a una funzione non gestita in modo che l'indirizzo non cambi in modo imprevisto durante la risoluzione della chiamata di funzione non gestita.

1dz8byfh.collapse_all(it-it,VS.110).gifSintassi

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

1dz8byfh.collapse_all(it-it,VS.110).gifParametri

  • più cv_qualifier
    const o qualificatori di volatile .Per impostazione predefinita, un puntatore di blocco volatile.è ridondante ma non un errore dichiarare un puntatore di blocco volatile.

  • tipo
    Tipo di initializer.

  • var
    Il nome della variabile di pin_ptr .

  • inizializzatore
    Un membro di un tipo di riferimento, dell'elemento della matrice gestita, o qualsiasi altro oggetto che è possibile assegnare a un puntatore nativo.

1dz8byfh.collapse_all(it-it,VS.110).gifNote

pin_ptr rappresenta un superset della funzionalità di un puntatore nativo.Di conseguenza, qualsiasi elemento che possa essere assegnato a un puntatore nativo può essere assegnato a pin_ptr.Un puntatore interno è consentito eseguire lo stesso set di operazioni dei puntatori nativi, incluso il confronto e l'aritmetica dei puntatori.

Un oggetto o un sotto-oggetto di una classe gestita può essere bloccato, nel qual caso il Common Language Runtime non la sposterà durante un'operazione di Garbage Collection.Possibilità principale di questa operazione è passare un puntatore ai dati gestiti come il parametro effettivo di una chiamata di funzione non gestita.Durante il ciclo di raccolta, il runtime nei metadati creati per un puntatore di blocco e non spostano l'elemento che indichi.

Bloccare un oggetto si blocca i relativi campi di valore; ovvero campi della primitiva o il tipo di valore.Tuttavia, i campi dichiarati tiene traccia di un handle (%) non sono bloccati.

Bloccare un sotto-oggetto definito in un oggetto gestito ha l'effetto di bloccare l'oggetto intera.

Se il puntatore di blocco viene rilocato per indicare un nuovo valore, l'istanza precedente a cui fa riferimento a non verrà più considerata bloccata.

Un oggetto è bloccato solo come punti di pin_ptr su.L'oggetto non è più bloccato quando il puntatore di blocco quando esce da, o è impostato su utilizzare nullptr.Dopo avere pin_ptr esce dall'ambito, l'oggetto che è bloccato può essere spostato nell'heap del Garbage Collector.Gli eventuali puntatori nativi non ancora indicano l'oggetto non verranno aggiornati e che de-di riferimento di essi possono generare un'eccezione irreversibile.

Se nessun punto dei puntatori di blocco all'oggetto (tutti i puntatori di blocco sono disconnesso di ambito, sono stati particolare per indicare altri oggetti, o sono stati assegnati utilizzare nullptr), l'oggetto è garantito non essere bloccato.

Un puntatore di blocco può indicare un handle di riferimento, handle del tipo boxed o il tipo di valore, membro di un tipo gestito, o un elemento di una matrice gestita.Non può indicare un tipo di riferimento.

La creazione dell'account di pin_ptr che indica un oggetto nativo determina il comportamento indefinito.

I puntatori di blocco possono essere dichiarati solo come variabili locali non statiche nello stack.

i puntatori di blocco non possono essere utilizzati come:

  • parametri di funzione

  • il tipo restituito di una funzione

  • un membro di una classe

  • il tipo di destinazione di cast.

pin_ptr si trova nello spazio dei nomi di cli .Per ulteriori informazioni, vedere Spazi dei nomi Platform, default e cli (Estensioni del componente C++).

Per ulteriori informazioni sui puntatori interni, vedere interior_ptr (C++/CLI).

Per ulteriori informazioni sui puntatori di blocco, vedere Procedura: bloccare puntatori e matrici e Procedura: dichiarare i puntatori di blocco e i tipi di valore.

1dz8byfh.collapse_all(it-it,VS.110).gifRequisiti

Opzione del compilatore: /clr

1dz8byfh.collapse_all(it-it,VS.110).gifEsempi

Esempio

Nell'esempio seguente viene utilizzato pin_ptr per limitare la posizione del primo elemento di una matrice.

// 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());
}

Output

  

Esempio

Nell'esempio seguente viene illustrato un puntatore interno può essere convertito in un puntatore di blocco e che il tipo restituito dell'operatore address-of (&) è un puntatore interno se l'operando è nell'heap gestito.

// 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);
};

Output

  

Esempio

Nell'esempio seguente viene illustrato un puntatore di blocco possibile eseguire il cast su un altro tipo.

// 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);
}

Output