Partilhar via


__pin

Observação   Este tópico se aplica somente à versão 1 de Managed Extensions for C++. Esta sintaxe só deve ser usada para manter o código da versão 1. Consulte pin_ptr para obter informações sobre como usar a funcionalidade equivalente na nova sintaxe.

Impede que um objeto ou um objeto inserido de uma classe gerenciada seja movido pelo Common Language Runtime durante a coleta de lixo.

__pin identifier

Comentários

A palavra-chave __pin declara um ponteiro para um objeto ou um objeto inserido de uma classe gerenciada e impede que esse objeto seja movido durante a coleta de lixo pelo Common Language Runtime. Isso é útil ao transmitir o endereço de uma classe gerenciada para uma função não gerenciada porque o endereço não será alterado de maneira inesperada durante a resolução da chamada da função não gerenciada.

Um ponteiro de fixação permanece válido no seu escopo léxico. Assim que o ponteiro de fixação sair do escopo, o objeto não será mais considerado fixado (a menos que, naturalmente, existam outros ponteiros de fixação que apontem para o objeto).

O MSIL não tem nenhum conceito de "escopo de bloqueio" -- todas as variáveis locais se encontram no escopo da função. Para informar ao sistema que o ponteiro de fixação não está mais em vigor, o compilador gera o código que atribui NULL ao ponteiro de fixação. Você também pode fazer isso sozinho, se precisar desafixar o objeto sem sair do bloco.

Você não deve converter seu ponteiro de fixação em um ponteiro não gerenciado e continuar usando esse ponteiro não gerenciado depois que o objeto não estiver mais fixado (depois que o ponteiro de fixação sair do escopo). Diferentemente dos ponteiros gc, os ponteiros de fixação podem ser convertidos em ponteiros nogc não gerenciados. No entanto, é responsabilidade do usuário manter o ponteiro de fixação enquanto o ponteiro não gerenciado está em uso.

Você não deve usar um ponteiro de fixação para obter o endereço de uma variável e, então, usar esse endereço depois que o ponteiro de fixação sair do escopo.

// keyword_pin_scope_bad.cpp
// compile with: /clr:oldSyntax /LD
#using <mscorlib.dll>
__gc struct X {
   int x;
};
 
int* Get_x( X* pX ) {
   int __pin* px = &pX -> x;
   return px;   // BE CAREFUL px goes of scope, 
                // so object pointed by it is no longer pinned,
                // making the return value unsafe.
}

O exemplo a seguir mostra o comportamento correto:

// keyword_pin_scope_good.cpp
// compile with: /clr:oldSyntax /LD
#using <mscorlib.dll>
__gc struct X {
   int x;
};
 
int Get_x( X* pX ) {
   int __pin* px = &pX -> x;
   return *px;   // OK, value obtained from px before px out of scope
}

Exemplo

No exemplo a seguir, o objeto apontado por pG é fixado até que seja retirado do escopo:

// keyword__pin.cpp
// compile with: /clr:oldSyntax
#using <mscorlib.dll>
#include <iostream>

__gc class G { 
public: 
   int i; 
   G() {i = 0;};
};

class H {
public:
   // unmanaged function
   void incr(int * i) {
      (*i)++; 
      std::cout << *i << std::endl;
   };
};

int main() {
   G __pin * pG = new G;  // pG is a pinning pointer
   H * h = new H;
   // pointer to managed data passed as actual parameter of unmanaged 
   // function call
   h->incr(& pG -> i); 
}

Saída

1