__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