pin_ptr (C++/CLI)
Deklaruje připnutí ukazatele, který se používá pouze s modulem CLR (Common Language Runtime).
Všechny moduly runtime
(Pro tuto funkci jazyka neexistují žádné poznámky, které platí pro všechny moduly runtime.)
prostředí Windows Runtime
(Tato funkce jazyka není v prostředí Windows Runtime podporovaná.)
CLR (Common Language Runtime)
Připnutí ukazatelem je vnitřní ukazatel , který brání objektu, na který odkazuje, aby se přesunul na haldu shromážděnou na paměti. To znamená, že hodnota připnutého ukazatele není změněna modulem CLR (Common Language Runtime). To se vyžaduje, když předáte adresu spravované třídy nespravované funkci, aby se adresa neočekávaně nezměnila během řešení nespravovaného volání funkce.
Syntaxe
[cli::]pin_ptr<cv_qualifiertype>var = &initializer;
Parametry
cv_qualifier
const
nebo volatile
kvalifikátory. Ve výchozím nastavení je volatile
připnutí ukazatelem . Je redundantní, ale není chyba deklarovat připnutí ukazatele volatile
.
type
Typ inicializátoru.
var
Název proměnné pin_ptr .
Inicializátor
Člen referenčního typu, prvku spravovaného pole nebo jakéhokoli jiného objektu, který můžete přiřadit nativnímu ukazateli.
Poznámky
Pin_ptr představuje nadmnožinu funkcí nativního ukazatele. Proto lze k pin_ptr přiřadit také cokoli, co lze přiřadit nativnímu ukazateli. Vnitřní ukazatel může provádět stejnou sadu operací jako nativní ukazatele, včetně porovnání a aritmetiky ukazatele.
Objekt nebo dílčí objekt spravované třídy je možné připnout, v takovém případě se modul CLR (Common Language Runtime) během uvolňování paměti nepřesune. Hlavním použitím tohoto objektu je předat ukazatel na spravovaná data jako skutečný parametr nespravovaného volání funkce. Během cyklu kolekce modul runtime zkontroluje metadata vytvořená pro připnutí ukazatele a nepřesune položku, na kterou odkazuje.
Připnutí objektu také připne jeho pole hodnot; to znamená pole primitivního typu nebo typu hodnoty. Pole deklarovaná pomocí popisovače sledování (%
) se ale nepřipnou.
Připnutí dílčího objektu definovaného ve spravovaném objektu má vliv na připnutí celého objektu.
Pokud je ukazatel připnutí znovu přiřazen tak, aby odkazoval na novou hodnotu, předchozí instance, na kterou odkazuje, se už nepovažuje za připnutou.
Objekt je připnutý pouze v době , kdy na něj pin_ptr odkazuje. Objekt už není připnutý, když ukazatel připnutí přejde mimo rozsah nebo je nastaven na nullptr. Jakmile pin_ptr zmizí z rozsahu, objekt, který byl připnut, lze přesunout do haldy uvolňováním paměti. Všechny nativní ukazatele, které stále odkazují na objekt, nebudou aktualizovány a zrušení odkazu na některý z nich může vyvolat neopravitelnou výjimku.
Pokud žádné připnuté ukazatele ukazují na objekt (všechny ukazatele připnutí byly mimo rozsah, byly znovu přiřazeny tak, aby odkazovaly na jiné objekty nebo byly přiřazeny nullptr), je zaručeno, že se objekt nepřipne.
Připnutí ukazatele může odkazovat na popisovač odkazu, typ hodnoty nebo krabicový popisovač typu, člen spravovaného typu nebo prvek spravovaného pole. Nemůže odkazovat na typ odkazu.
Když vezmete adresu pin_ptr , která odkazuje na nativní objekt, způsobí nedefinované chování.
Připnutí ukazatelů lze deklarovat pouze jako nestatické místní proměnné v zásobníku.
Připnutí ukazatelů nelze použít jako:
funkční parametry
návratový typ funkce
člen třídy
cílový typ přetypování.
pin_ptr je v cli
oboru názvů. Další informace najdete v tématu Obory názvů platformy, výchozího nastavení a rozhraní příkazového řádku.
Další informace o vnitřních ukazatelích najdete v tématu interior_ptr (C++/CLI).
Další informace o připnutí ukazatelů naleznete v tématu Postupy: Připnutí ukazatelů a polí a postupy: Deklarace připnutí ukazatelů a typů hodnot.
Požadavky
Možnost kompilátoru: /clr
Příklady
Následující příklad používá pin_ptr k omezení pozice prvního prvku pole.
// 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());
}
45
Následující příklad ukazuje, že vnitřní ukazatel lze převést na připnutí ukazatele a že návratový typ operátoru adresa (&
) je vnitřní ukazatel, když je operand na spravované haldě.
// 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);
};
1
Následující příklad ukazuje, že připnutí ukazatele lze přetypovat na jiný typ.
// 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);
}
8
255