pin_ptr (C++/CLI)
Declara um ponteiro fixando-se, que é usado apenas com Common Language Runtime.
Todos os Tempos de Execução
(Não há nenhum comentário sobre este recurso de linguagem que se aplica a todos os tempos de execução).
Tempo de execução do windows
(Esse recurso de idioma não tem suporte em Tempo de Execução do Windows).
Common Language Runtime
Um ponteiro fixando-se é um ponteiro interior que evite o objeto apontado a movimentação no heap com coletados. Isto é, o valor de um ponteiro fixando-se não é alterado por Common Language Runtime. Isso é necessário quando você passa o endereço de uma classe gerenciada em uma função não gerenciados de forma que o endereço não é alterada inesperadamente durante a resolução da chamada de função não gerenciado.
Sintaxe
[cli::]pin_ptr<cv_qualifier type> var = &initializer;
Parâmetros
cv_qualifier
const ou qualificadores de volatile . Por padrão, um ponteiro fixando-se é volatile. É redundante mas não um erro declarar um ponteiro fixando-se volatile.type
O tipo de initializer.var
O nome da variável de pin_ptr .initializer
Um membro de um tipo de referência, do elemento de uma matriz gerenciado, ou qualquer outro objeto que você pode atribuir a um ponteiro nativo.
Comentários
pin_ptr representa um superconjunto da funcionalidade de um ponteiro nativo. Em virtude disso, qualquer coisa que pode ser atribuído a um ponteiro nativo também pode ser atribuído a pin_ptr. Um ponteiro interior tem permissão para executar o mesmo conjunto de operações que ponteiros nativos, incluindo a comparação e aritmética do ponteiro.
Um objeto ou um novo objeto de uma classe gerenciado podem ser definidos nesse caso, Common Language Runtime não a movido durante a coleta de lixo. O principal uso deste é transmitir um ponteiro para os dados gerenciados como um parâmetro real de uma chamada de função não gerenciado. Durante um ciclo de coleta, o tempo de execução inspecionará os metadados criados para o ponteiro fixando-se e não será movido o item que aponte para.
Fixando um objeto também fixa os campos de valor; ou seja, campos de primitivo ou de tipo de valor. No entanto, os campos declarados controlando o identificador%() não são fixados.
Fixar um novo objeto definido em um objeto gerenciado tem o efeito de fixar o objeto inteiro.
Se o ponteiro se fixando é reatribuído para apontar para um novo valor, a instância anterior apontada é considerada não fixada.
Um objeto é fixado somente quando pontos de pin_ptr a ele. O objeto é fixado não quando o ponteiro se fixando sair do escopo, ou definido como nullptr. Depois que pin_ptr sair do escopo, o objeto que foi fixado pode ser movido para o heap pelo coletor de lixo. Nenhum ponteiros nativas que apontam para o objeto ainda não serão atualizados, e o MDS referenciando um deless podem gerar uma exceção irrecuperável.
Se nenhum ponto se fixando dos ponteiros ao objeto (todos os ponteiros se fixando saíram do escopo, foram atribuídos novamente para apontar para outros objetos, ou atribuídos nullptr), o objeto não há garantia de ser fixado.
Um ponteiro fixando-se pode apontar para um identificador de referência, um tipo de valor ou identificador encaixotada do tipo, membro de um tipo gerenciado, ou um elemento de uma matriz gerenciado. Não pode apontar para um tipo de referência.
Colocar o endereço de pin_ptr que aponta para um objeto nativo causa comportamento indefinido.
Fixar ponteiros só pode ser declarado como variáveis locais de não estático na pilha.
Fixar ponteiros não pode ser usado como:
parâmetros de função
o tipo de retorno de uma função
um membro de uma classe
o tipo de destino de uma conversão.
pin_ptr está no namespace de cli . Para obter mais informações, consulte Namespaces Plataforma, padrão e cli (Extensões de Componentes C++).
Para obter mais informações sobre os ponteiros interiores, consulte interior_ptr (C++/CLI).
Para obter mais informações sobre como manter os ponteiros, consulte Como fixar ponteiros e matrizes e Como declarar ponteiros de fixação e tipos de valor.
Requisitos
Opção do compilador: /clr
Exemplos
Exemplo
O exemplo a seguir usa pin_ptr para restringir a posição do primeiro elemento de uma matriz.
// 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());
}
Saída
Exemplo
O exemplo a seguir mostra que um ponteiro interior pode ser convertido em um ponteiro se fixando, e que o tipo de retorno de endereços do operador (&) é um ponteiro interior quando o operando estiver no heap gerenciado.
// 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);
};
Saída
1
Exemplo
O exemplo a seguir mostra que um ponteiro se fixando pode ser convertido em outro 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);
}
Saída
8