En utilisant IntelliSense et en regardant le code des autres, j'ai rencontré ce IntPtr
type; chaque fois qu'il a eu besoin d'être utilisé, j'ai simplement mis null
ou IntPtr.Zero
trouvé la plupart des fonctions pour fonctionner. De quoi s'agit-il exactement et quand / pourquoi est-il utilisé?
171
IntPtr
est parfaitement logique, car c'est un entier (comme dans un entier mathématique) et un pointeur (comme dans un pointeur). LaInt
partie a peu à voir avec le type int - c'est un concept, pas un type spécifique. Bien que pour être honnête, la seule chose que la spécification CLI dit à ce sujet est qu'il s'agit bien d'une "taille entière, native". Oh bien :)C'est un type de valeur suffisamment grand pour stocker une adresse mémoire telle qu'elle est utilisée dans un code natif ou non sécurisé, mais pas directement utilisable comme adresse mémoire dans un code managé sécurisé.
Vous pouvez utiliser
IntPtr.Size
pour savoir si vous exécutez dans un processus 32 bits ou 64 bits, car ce sera respectivement 4 ou 8 octets.la source
IntPtr
est également utilisé pour représenter des poignées qui sont 32 bits quelle que soit l'architecture (bien queSize
toujours dit 8 dans ce cas). La spécification CLI note seulement que c'est un entier qui est de "taille native", mais cela ne dit pas grand-chose, vraiment.Voici un exemple:
J'écris un programme C # qui s'interface avec une caméra haute vitesse. L'appareil photo a son propre pilote qui acquiert les images et les charge automatiquement dans la mémoire de l'ordinateur.
Ainsi, lorsque je suis prêt à intégrer la dernière image dans mon programme pour travailler avec, le pilote de la caméra me fournit un IntPtr où l'image est DÉJÀ stockée dans la mémoire physique, donc je n'ai pas à perdre de temps / ressources en créant une autre bloc de mémoire pour stocker une image déjà en mémoire. L'IntPtr me montre simplement où se trouve déjà l'image.
la source
Une interprétation directe
Un 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écurisé», la plomberie entre les segments de code non sécurisés peut être implémentée dans un code de haut niveau plus sûr - ou même dans un langage .NET qui ne prend pas directement en charge les pointeurs.
La taille d'IntPtr est spécifique à la plate-forme, mais ce détail doit rarement être pris en compte, car le système utilisera automatiquement la taille correcte.
Le nom «IntPtr» est déroutant - quelque chose comme cela
Handle
aurait pu être plus approprié. Ma première estimation était que "IntPtr" était un pointeur vers un entier. La documentation MSDN d'IntPtr entre dans des détails quelque peu cryptiques sans jamais donner beaucoup d'informations sur la signification du nom.Une perspective alternative
An
IntPtr
est un pointeur avec deux limitations:En d'autres termes, un
IntPtr
est juste comme unvoid*
- mais avec la fonctionnalité supplémentaire qu'il peut (mais ne devrait pas) être utilisé pour l'arithmétique de base des pointeurs.Pour déréférencer un
IntPtr
, vous pouvez soit le convertir en un vrai pointeur (une opération qui ne peut être effectuée que dans des contextes «non sûrs»), soit le transmettre à une routine d'assistance telle que celles fournies par laInteropServices.Marshal
classe. L'utilisation de laMarshal
classe donne l'illusion de la sécurité puisqu'elle ne vous oblige pas à être dans un contexte explicite «dangereux». Cependant, cela ne supprime pas le risque de plantage inhérent à l'utilisation de pointeurs.la source
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 indiquer l' adresse sur laquelle ils pointent ou la valeur à l'adresse qu'ils pointent.
Un pointeur peut être considéré comme une sorte de marque-page. Sauf qu'au lieu d'être utilisé pour accéder rapidement à une page d'un livre, un pointeur est utilisé pour suivre ou mapper des blocs de mémoire.
Imaginez la mémoire de votre programme exactement comme un grand tableau de 65535 octets.
Les pointeurs pointent docilement
Les pointeurs mémorisent chacun une adresse mémoire et pointent donc chacun vers une seule adresse en mémoire.
En tant que groupe, les pointeurs mémorisent et rappellent les adresses de mémoire, obéissant à chacune de vos commandes ad nauseum.
Tu es leur roi.
Pointeurs en C #
Egalement spécifiques à C #, les pointeurs sont de type int et donc signés.
Cependant, vous ne pouvez pas utiliser d'adresses numérotées négativement, ni accéder à une adresse supérieure à 65534. Toute tentative de le faire lèvera une exception System.AccessViolationException.
Un pointeur appelé MyPointer est déclaré comme ceci:
Un pointeur en C # est un entier, mais les adresses mémoire en C # commencent à 0 et s'étendent jusqu'à 65534.
Les objets pointus doivent être manipulés avec un soin tout particulier
Le mot unsafe est destiné à vous effrayer, et pour une très bonne raison: les pointeurs sont des objets pointus, et les objets pointus comme les épées, les haches, les pointeurs, etc. doivent être manipulés avec un soin particulier.
Les pointeurs permettent au programmeur de contrôler étroitement un système. Par conséquent, les erreurs commises risquent d'avoir des conséquences plus graves.
Pour utiliser des pointeurs, le code non sécurisé 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 non sécurisés.
Exemple de bloc non sécurisé
Comment utiliser les pointeurs
Lorsque des variables ou des objets sont déclarés ou instanciés, ils sont stockés en mémoire.
int *MyPointer;
MyPointer = &MyVariable;
Une fois qu'une adresse est attribuée à un pointeur, ce qui suit s'applique:
MyPointer = &MyVariable; // Set MyPointer to point at MyVariable
"MyPointer is pointing at " + *MyPointer;
Étant donné qu'un pointeur est une variable contenant une adresse mémoire, cette adresse mémoire peut être stockée dans une variable pointeur.
Exemple de pointeurs utilisés avec soin et de manière responsable
Notez que le type du pointeur est un int. C'est parce que C # interprète les adresses mémoire comme des nombres entiers (int).
Pourquoi est-il int au lieu de uint?
Il n'y a aucune bonne raison.
Pourquoi utiliser des pointeurs?
Les pointeurs sont très amusants. Avec une grande partie de l'ordinateur contrôlée par la mémoire, les pointeurs permettent au programmeur de mieux contrôler la mémoire de son programme.
Surveillance de la mémoire.
Utilisez des pointeurs pour lire des blocs de mémoire et surveiller la façon dont les valeurs pointées changent au fil du temps.
Modifiez ces valeurs de manière responsable et suivez la manière dont vos modifications affectent votre ordinateur.
la source
65534
semble très faux comme plage de pointeur. Vous devez fournir une référence.System.IntPtr
. J'aimerais voir la réponse mise à jour à la fin expliquant ce qu'est également unSystem.IntPtr
et comment il se rapporte aux pointeurs non sécurisés en C # s'il vous plaît.MSDN nous dit:
http://msdn.microsoft.com/en-us/library/system.intptr(VS.71).aspx
la source
Eh bien, c'est la page MSDN qui traite
IntPtr
.La première ligne se lit comme suit:
Quant à ce qu'est un pointeur ou une poignée, la page continue à indiquer:
Un pointeur est une référence à une zone de mémoire qui contient certaines données qui vous intéressent.
Un handle peut être un identifiant pour un objet et est passé entre les méthodes / classes lorsque les deux côtés ont besoin d'accéder à cet objet.
la source
An
IntPtr
est un type de valeur principalement utilisé pour contenir des adresses mémoire ou des descripteurs. Un pointeur est une adresse mémoire. Un pointeur peut être tapé (par exempleint*
) ou non typé (par exemplevoid*
). Un handle Windows est une valeur qui est généralement de la même taille (ou plus petite) qu'une adresse mémoire et représente une ressource système (comme un fichier ou une fenêtre).la source