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é?

150
demandé sur Callum Rogers 2009-07-18 22:13:00

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).

139
répondu Sam Harwell 2009-07-18 18:15:06

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.

55
répondu Daniel Earwicker 2016-09-20 22:58:02

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à.

34
répondu bufferz 2009-07-18 19:24:36

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:

  1. Elle ne peut être déréférencé
  2. 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.

31
répondu nobar 2017-05-23 11:47:26

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 pointeurs

se 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 pointeurs

donnent 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.

8
répondu Knickerless-Noggins 2017-03-29 07:43:28

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 objets

IntPtr 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

7
répondu Zyphrax 2009-07-18 18:15:44

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 objets

IntPtr 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.

5
répondu ChrisF 2009-07-18 18:20:51