2009-10-30 9 views
1

Je trouve le code du filet dans lequel je ne peux pas comprendre cette ligne: -Expliquer ce code C#: octet * p = (octet *) (void *) Scan0;

byte* p = (byte*)(void*)Scan0; 

Il est scan0 System.IntPtr. C'est le code de C# .Net. Plz Explique la ligne ci-dessus.

Le code complet est donné ci-dessous. C'est un code pour convertir une image en niveaux de gris. Je comprends tout le code mais je n'ai que le problème sur cette ligne

public static Image GrayScale(Bitmap b) 
    { 

     BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 

     int stride = bmData.Stride; 
     System.IntPtr Scan0 = bmData.Scan0; 

     unsafe 
     { 
      byte* p = (byte*)(void*)Scan0; 

      int nOffset = stride - b.Width * 3; 

      byte red, green, blue; 

      for (int y = 0; y < b.Height; ++y) 
      { 
       for (int x = 0; x < b.Width; ++x) 
       { 
        blue = p[0]; 
        green = p[1]; 
        red = p[2]; 

        p[0] = p[1] = p[2] = (byte)(.299 * red + .587 * green + .114 * blue); 

        p += 3; 
       } 
       p += nOffset; 
      } 
     } 

     b.UnlockBits(bmData); 

     return (Image)b; 
    } 

byte* p = (byte*)(void*)Scan0; 
+10

Il se trouve être orthographié "s'il vous plaît". –

Répondre

5

convertit d'abord le IntPtr à un pointeur void. Puis à un pointeur byte. C'est le code unsafe.

Plus sur le code dangereux: http://msdn.microsoft.com/en-us/library/aa288474%28VS.71%29.aspx

Comme Robert Harvey fait remarquer, un pointeur est un emplacement de mémoire. Dans les tableaux C/C++ sont étroitement liés à ce concept. Quand il fait les crochets, il ajuste fondamentalement l'adresse.

+0

Merci monsieur, je comprends le concept de pointeurs et de code dangereux. Pouvez-vous donner plus d'explications sur les pointeurs de vide. – qulzam

+3

Un pointeur vide est, d'une manière très rudimentaire, un pointeur vers AUCUN TYPE SPÉCIFIQUE. Ainsi, vous obtenez un pointeur vers une adresse qui ne fait référence à aucun type, simplement les données à cette adresse. Ensuite, vous êtes libre de le lancer à tout ce que vous voulez. Dans cet exemple, ils lancent un Int dans un vide (rien). Le pointeur vide (une adresse de mémoire brute) est ensuite casté à l'adresse d'un octet. (Bon dieu, ça fait longtemps que j'ai travaillé avec ça, quelqu'un me corrige si je me trompe.) –

1

Cela semble bizarre, mais je ne connais pas très bien le C#. Il peut être qu'il ya un problème avec un casting System.IntPtr directement à un byte*, mais pas avec System.IntPtr à void* ou void* à byte*.

Le résultat final est probablement le même que si vous lancez int* à char* dans C: la capacité de derefence p pour obtenir un seul octet de l'entier (en supposant CHAR_BIT est 8 dans la mise en œuvre C).

1

Découvrez ce tutoriel sur le code dangereux. Il vous expliquera ce que la ligne de code signifie, et comment il peut être utilisé pour d'autres types d'ailleurs octet:

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

Essentiellement, le code dangereux vous permet d'utiliser des pointeurs de style c.

+0

Je comprends le code dangereux, mais il y a une certaine confusion que signifie (byte *) (void *) – qulzam

4

Votre question semble que si vous demandez ce le code est fait, mais d'après certains de vos commentaires, je pense que vous êtes après pourquoi il jette d'abord à un pointeur vide.

Vous êtes probablement confus ici car il n'y a aucune raison de lancer Scan0 d'abord dans un vide *. La distribution en byte * fonctionnerait aussi bien.

0

Serait-il possible que vous deviez transtyper à void pour éviter que l'objet n'exécute du code d'auto-cast?

2

IntPtr dispose d'un opérateur explicite (void *) qui permet de lancer l'annulation *. Si vous essayez de convertir directement IntPtr en quelque chose d'autre, le compilateur apparaîtra car seul le cast void * est défini pour la classe IntPtr. Voir aussi IntPtr :: ToPointer().

La conversion de void * en byte * est autorisée par le compilateur car à ce stade, si vous ne savez pas ce que vous faites, vous avez déjà des problèmes.