Juste ce qui est un IntPtr exactement?
en utilisant IntelliSense et en regardant le code d'autres personnes, je suis tombé sur ce type IntPtr
; chaque fois qu'il a dû être utilisé, j'ai simplement mis null
ou IntPtr.Zero
et j'ai trouvé la plupart des fonctions à travailler. Qu'est-il exactement et quand/pourquoi est-il utilisé?
7 réponses
c'est un" entier de taille natif (spécifique à la plate-forme)."Il est représenté comme void*
mais exposé comme un entier. Vous pouvez l'utiliser chaque fois que vous avez besoin de stocker un pointeur non géré et ne veulent pas utiliser le code unsafe
. IntPtr.Zero
est effectivement NULL
(un pointeur nul).
c'est un type de valeur assez grand pour stocker une adresse mémoire comme utilisé dans le code natif ou dangereux, mais pas directement utilisable comme une adresse mémoire dans le code géré en toute sécurité.
vous pouvez utiliser IntPtr.Size
pour savoir si vous utilisez un processus 32 bits ou 64 bits, car il sera de 4 ou 8 octets respectivement.
voici un exemple:
j'écris un programme C# qui s'interface avec une caméra à grande vitesse. La caméra a son propre pilote qui acquiert les images et les charge dans la mémoire de l'ordinateur pour moi automatiquement.
ainsi quand je suis prêt à apporter la dernière image dans mon programme pour travailler avec, le pilote de caméra me fournit un IntPtr à où à l'image est déjà stocké dans la mémoire physique, de sorte que je n'ai pas à perdre de temps / ressources création un autre bloc de mémoire pour stocker une image dans la mémoire déjà. L'IntPtr me montre juste où l'image est déjà.
Une interprétation directe de la
Un IntPtr est un integer , qui est la même taille qu'un pointeur .
vous pouvez utiliser IntPtr pour stocker une valeur de pointeur dans un type non-pointeur. Cette fonctionnalité est importante dans .NET car l'utilisation de pointeurs est très sujette aux erreurs et donc illégale dans la plupart des contextes. En permettant à la valeur du pointeur d'être stocké dans un type de données" sûr", la plomberie entre "unsafe " les segments de code peuvent être implémentés dans du code de haut niveau plus sûr -- ou même dans un langage .NET qui ne supporte pas directement les pointeurs.
la taille de L'IntPtr est spécifique à la plate-forme, mais ce détail doit rarement être pris en considération, puisque le système utilisera automatiquement la bonne taille.
le nom" IntPtr "prête à confusion -- quelque chose comme Handle
aurait pu être plus approprié. Ma première supposition était que "IntPtr "était un pointeur à un entier. La documentation MSDN de L'IntPtr entre dans des détails quelque peu cryptiques sans jamais fournir beaucoup de perspicacité sur la signification du nom.
une perspective alternative
Un IntPtr
est un pointeur avec deux limites:
- Elle ne peut être déréférencé
- il ne sait pas le type de les données qu'il indique.
en d'autres termes, un IntPtr
est comme un void*
-- mais avec la caractéristique supplémentaire qu'il peut (mais ne devrait pas) être utilisé pour l'arithmétique pointeur de base.
pour déréférencer un IntPtr
, vous pouvez soit le lancer sur un vrai pointeur (une opération qui ne peut être effectuée que dans des contextes "dangereux"), soit le passer à une routine d'aide comme celles fournies par le InteropServices.Marshal
de la classe. L'utilisation de la classe Marshal
donne l'illusion de la sécurité puisqu'elle n'exige pas que vous soyez dans un contexte" dangereux " explicite. Cependant, il ne supprime pas le risque de s'écraser qui est inhérent à l'utilisation de pointeurs.
Qu'est-ce qu'un pointeur?
dans toutes les langues, un pointeur est un type de variable qui stocke une adresse mémoire, et vous pouvez soit leur demander de vous dire le adresse ils pointent vers ou la valeur à l'adresse ils pointent vers.
Un pointeur peut être considéré comme une sorte de livre marque. Sauf qu'au lieu d'être utilisée pour accéder rapidement à une page dans un livre, un pointeur est utilisé pour garder une trace ou cartographier des blocs de mémoire.
Imaginez la mémoire de votre programme exactement comme un grand tableau de 65535 octets.
pointeurs point obediently
Les pointeursse souviennent d'une adresse mémoire chacun, et donc ils pointent vers une seule adresse mémoire.
en tant que groupe, les pointeurs se souviennent et rappellent les adresses de mémoire, obéissant à tous vos ordres ad nauseum.
tu es leur roi.
pointeurs en C#
spécifiquement dans C#, Un pointeur est une variable entière qui stocke une adresse mémoire entre 0 et 65534.
aussi spécifique à C#, Les pointeurs sont de type int et donc signés.
vous ne pouvez pas utiliser des adresses numérotées négativement cependant, vous ne pouvez pas non plus accéder à une adresse au-dessus de 65534. Toute tentative en ce sens lancera un système.AccessViolationException.
un pointeur appelé MyPointer est déclaré comme suit:
int *MyPointer;
un pointeur en C# est un int, mais les adresses mémoire en C# commencent à 0 et s'étendent jusqu'à 65534.
les objets pointus doivent être manipulés avec un soin particulier
Le mot dangereux est destiné à vous effrayer, et pour une très bonne raison: les pointeurs sont des choses pointues, et des choses pointues par exemple des épées, des haches, des pointeurs, etc. doit être manipulée avec un soin particulier.
Les pointeursdonnent au programmeur un contrôle serré du système. Les erreurs commises risquent donc d'avoir des conséquences plus graves.
pour utiliser des pointeurs, le code dangereux doit être activé dans les propriétés de votre programme, et les pointeurs doivent être utilisés exclusivement dans des méthodes ou des blocs marqués comme dangereux.
exemple de bloc dangereux
unsafe
{
// Place code carefully and responsibly here.
}
comment utiliser les pointeurs
lorsque des variables ou des objets sont déclarés ou instanciés, ils sont stockés en mémoire.
- déclarez un pointeur en utilisant le préfixe du symbole*.
int *MyPointer;
- Pour obtenir l'adresse d'une variable, vous utilisez le symbole du préfixe.
MyPointer = &MyVariable;
une fois qu'une adresse est assignée à un pointeur, ce qui suit s'applique:
- sans préfixe * pour faire référence à l'adresse mémoire pointée comme int.
MyPointer = &MyVariable; // Set MyPointer to point at MyVariable
- avec le préfixe * pour obtenir le valeur stockée à l'adresse de mémoire d'être souligné.
"MyPointer is pointing at " + *MyPointer;
Depuis un pointeur est une variable qui contient une adresse mémoire, cette mémoire adresse peut être stockée dans une variable du pointeur.
exemple d'utilisation prudente et responsable de pointeurs
public unsafe void PointerTest()
{
int x = 100; // Create a variable named x
int *MyPointer = &x; // Store the address of variable named x into the pointer named MyPointer
textBox1.Text = ((int)MyPointer).ToString(); // Displays the memory address stored in pointer named MyPointer
textBox2.Text = (*MyPointer).ToString(); // Displays the value of the variable named x via the pointer named MyPointer.
}
notez que le type de pointeur est un int. C'est parce que C# interprète les adresses mémoire comme nombres entiers (int).
Pourquoi est-ce l'int au lieu de l'uint?
Il n'y a pas de bonne raison.
Pourquoi utiliser des pointeurs?
Pointeurs sont beaucoup de plaisir. Avec une telle partie de l'ordinateur étant contrôlée par la mémoire, les pointeurs habilitent un programmeur avec plus de contrôle de la mémoire de leur programme.
surveillance de la mémoire.
utilisez des pointeurs pour lire des blocs de mémoire et surveiller comment les valeurs pointées changent avec le temps.
changez ces valeurs de façon responsable et gardez une trace de la façon dont vos changements affectent votre ordinateur.
MSDN nous dit:
le type IntPtr est conçu pour être un entier dont la taille est une plate-forme spécifique. C'est, une une instance de ce type devrait: être 32 bits sur le matériel 32 bits et systèmes d'exploitation, et 64 bits sur Matériel 64 bits et systèmes d'exploitation.
le type IntPtr peut être utilisé par langues de soutien des pointeurs, et comme moyen commun de se référer aux données entre les langues qui ne pas pointeurs de soutien.
Les objetsIntPtr peuvent également être utilisés pour maintenez les poignées. Par exemple, en cas de L'IntPtr sont largement utilisés dans le Système.IO.Classe de FileStream à tenir poignées de dossiers.
le type IntPtr est conforme au CLS, alors que le type UIntPtr ne l'est pas. Seulement le type IntPtr est utilisé dans les language runtime. Le type UIntPtr est principalement fournis pour maintenir symétrie architecturale avec L'IntPtr type.
http://msdn.microsoft.com/en-us/library/system.intptr (VS.71).aspx
C'est la page MSDN qui traite de IntPtr
.
la première ligne se lit:
un type spécifique à une plate-forme qui est utilisé pour représenter un pointeur ou une poignée.
quant à ce qu'est un pointeur ou une poignée la page poursuit en disant:
le type IntPtr peut être utilisé par langues de soutien des pointeurs, et en tant que commune moyens de référence des données entre les langues qui ne sont pas pointeurs de soutien.
Les objetsIntPtr peuvent également être utilisés pour maintenez les poignées. Par exemple, en cas de L'IntPtr sont largement utilisés dans le Système.IO.Classe de FileStream à tenir poignées de dossiers.
Un pointeur est une référence à une zone de mémoire qui contient quelques données qui vous intéressent.
Une poignée peut être un identificateur d'un objet et est transmis entre les méthodes/classes lorsque les deux côtés doivent accéder à cet objet.