180 votes

Qu'est-ce qu'un IntPtr exactement ?

En utilisant IntelliSense et en regardant le code d'autres personnes, j'ai trouvé ceci IntPtr chaque fois qu'il a été nécessaire de l'utiliser, j'ai simplement mis null ou IntPtr.Zero et j'ai constaté que la plupart des fonctions fonctionnent. De quoi s'agit-il exactement et quand/pourquoi est-il utilisé ?

169voto

280Z28 Points 49515

C'est un "entier de taille native (spécifique à la plate-forme)". Il est représenté en interne par void* mais exposé comme un entier. Vous pouvez l'utiliser chaque fois que vous avez besoin de stocker un pointeur non géré et que vous ne voulez pas utiliser la fonction unsafe code. IntPtr.Zero est effectivement NULL (un pointeur nul).

55 votes

Un pointeur est quelque chose qui pointe vers une adresse en mémoire. Dans les langages gérés, vous avez des références (l'adresse peut se déplacer), tandis que dans les langages non gérés, vous avez des pointeurs (l'adresse est fixe).

96 votes

En général (dans tous les langages de programmation), un pointeur est un nombre qui représente un emplacement physique dans la mémoire. A null Un pointeur est (presque toujours) un pointeur qui pointe vers 0, et est largement reconnu comme "ne pointant vers rien". Étant donné que les systèmes ont des quantités différentes de mémoire supportée, il ne faut pas toujours le même nombre d'octets pour contenir ce nombre, c'est pourquoi nous appelons un "entier de taille native" celui qui peut contenir un pointeur sur un système particulier.

5 votes

+1 pour ce commentaire @280Z28, c'est l'explication la plus succincte des pointeurs que j'ai jamais vue.

73voto

Daniel Earwicker Points 63298

Il s'agit d'un type de valeur suffisamment grand pour stocker une adresse mémoire telle qu'utilisée dans le code natif ou non sécurisé, mais qui n'est pas directement utilisable comme adresse mémoire dans le code géré sécurisé.

Vous pouvez utiliser IntPtr.Size pour savoir si vous êtes dans un processus 32 bits ou 64 bits, car il s'agira respectivement de 4 ou 8 octets.

17 votes

Bon point concernant la détection de la taille de l'espace d'adressage pour le processus.

0 votes

@Noldorin Vrai, mais pas nécessairement fiable. Dans le passé, il y a eu beaucoup d'architectures qui avaient plusieurs types de pointeurs, et sous Windows, IntPtr est également utilisé pour représenter les poignées qui sont 32-bit indépendamment de l'architecture (bien que Size dit toujours 8 dans ce cas). La spécification CLI indique seulement qu'il s'agit d'un entier de "taille native", mais cela ne veut pas dire grand-chose.

0 votes

@Luaan cela ne change pas grand chose à ma réponse, n'est-ce pas ? IntPtr est appelé ainsi (et est utilisé dans toute la source CLR) comme une valeur assez grande pour contenir une adresse mémoire. Il peut contenir des valeurs plus petites bien sûr. Certaines architectures ont plusieurs types de pointeurs, mais doivent avoir celui qui est le plus grand de l'ensemble.

54voto

bufferz Points 1590

Voici un exemple :

J'écris un programme C# qui s'interface avec une caméra à haute vitesse. La caméra a son propre pilote qui acquiert les images et les charge automatiquement dans la mémoire de l'ordinateur pour moi.

Ainsi, lorsque je suis prêt à intégrer la dernière image dans mon programme pour travailler, le pilote de la caméra me fournit une IntPtr vers l'endroit où l'image est DÉJÀ stockée dans la mémoire physique, de sorte que je n'ai pas à perdre de temps/ressources à créer un autre bloc de mémoire pour stocker une image qui est déjà en mémoire. L'IntPtr m'indique simplement où se trouve déjà l'image.

7 votes

Donc, le IntPtr simple vous permet d'utiliser un pointeur non géré (comme celui utilisé dans votre pilote de caméra) dans du code géré ?

5 votes

Oui. Dans ce cas, il est fort probable que le pilote de la caméra utilise des pilotes non gérés sous le capot, mais afin de fonctionner correctement dans le monde géré uniquement, il fournit l'IntPtr pour me permettre de travailler avec les données en toute sécurité.

3 votes

Alors pourquoi ne vous renvoie-t-il pas simplement un flux (tableau d'octets) ? Pourquoi n'est-il pas sûr ou incapable de renvoyer la valeur ?

42voto

nobar Points 5849

Une interprétation directe

Un site IntPtr est un entier qui a 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ée dans un type de données "sûr", la plomberie entre non sécurisé Les segments de code peuvent être mis en œuvre dans un code de haut niveau plus sûr, voire dans un langage .NET qui ne prend pas directement en charge les pointeurs.

La taille de IntPtr est spécifique à la plate-forme, mais ce détail a rarement besoin d'être pris en compte, puisque le système utilisera automatiquement la taille correcte.

Le nom "IntPtr" prête à confusion -- quelque chose comme Handle aurait pu être plus approprié. Ma supposition initiale était que "IntPtr" était un pointeur à un nombre entier. Le site Documentation MSDN de IntPtr entre dans des détails quelque peu énigmatiques, sans jamais donner d'indications sur la signification du nom.

Une autre perspective

Un site IntPtr est un pointeur avec deux limitations :

  1. Il ne peut pas être déréférencé directement
  2. Il ne connaît pas le type des données vers lesquelles il pointe.

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 de base des pointeurs.

Afin de déréférencer un IntPtr vous pouvez soit le convertir en un pointeur vrai (une opération qui ne peut être effectuée que dans des contextes "non sécurisés"), soit le passer à une routine d'aide telle que celles fournies par la méthode d'aide à la résolution des problèmes. InteropServices.Marshal classe. En utilisant le Marshal donne l'illusion de la sécurité puisqu'elle ne nécessite pas d'être dans un contexte explicite "non sûr". Cependant, elle ne supprime pas le risque de plantage qui est inhérent à l'utilisation de pointeurs.

2 votes

Il existe un précédent pour le nom "intptr" dans la norme C99 du langage de programmation "C". linux.die.net/man/3/intptr_t .

7voto

Zyphrax Points 6603

MSDN nous le dit :

Le type IntPtr est conçu pour être un entier dont la taille est spécifique à la plate-forme. C'est-à-dire qu'une instance de ce type est censée 32 bits sur du matériel 32 bits et des systèmes d'exploitation 32 bits, et 64 bits sur 64 bits sur du matériel et des systèmes d'exploitation 64 bits.

Le type IntPtr peut être utilisé par les langages qui supportent les pointeurs, et comme un moyen commun de se référer à des données entre les langages qui supportent ou non supportent pas les pointeurs.

Les objets IntPtr peuvent également être utilisés pour contenir des poignées. Par exemple, les instances d'IntPtr sont largement utilisées dans la classe classe System.IO.FileStream pour contenir les les identifiants de fichiers.

Le type IntPtr est conforme à la norme CLS, alors que le type UIntPtr ne l'est pas. Seulement le type IntPtr est utilisé dans le runtime du langage commun. Le type UIntPtr est fourni principalement pour maintenir symétrie architecturale avec le type IntPtr et le type IntPtr.

http://msdn.microsoft.com/en-us/library/system.intptr(VS.71).aspx

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X