__pin
Publicado: abril de 2016
Observação neste 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 (C++/CLI) para obter informações sobre como usar a funcionalidade equivalente na nova sintaxe.
Impede que um objeto ou incorporado de uma classe gerenciada seja movido pelo common language runtime durante a coleta de lixo.
Sintaxe
__pin
identifier
Comentários
O __pin palavra-chave declara um ponteiro para um objeto ou incorporado de uma classe gerenciada e impede que o objeto seja movido durante a coleta de lixo pelo common language runtime. Isso é útil ao passar o endereço de uma classe gerenciada para uma função não gerenciada porque o endereço não será alterado inesperadamente durante a resolução da chamada de 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 é mais considerado fixado (a menos, é claro, existem outros ponteiros de fixação apontando para ou no objeto).
O MSIL não tem nenhum conceito de "escopo de bloco"--ao vivo todas as variáveis locais no escopo da função. Para informar ao sistema que a fixação não está mais em vigor, o compilador gera código que atribui NULL ao ponteiro de fixação. Isso também é que você pode fazer por conta própria, se você 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). Ao contrário dos ponteiros gc, fixando ponteiros pode ser convertido para nogc, ponteiros não gerenciados. No entanto, é responsabilidade do usuário para manter a fixação enquanto o ponteiro não gerenciado está em uso.
Usando um ponteiro de fixação para obter o endereço de uma variável e, em seguida, usar esse endereço depois que o ponteiro de fixação sair do escopo, não deve ser feito.
// 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 ele passa fora 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