1

この行を理解できないネットからコードを見つけました:-

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

Scan0 はSystem.IntPtr です。 C#.Netのコードです。上記の行について説明してください。

完全なコードを以下に示します。これは画像をグレースケールに変換するコードです。

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;
4

6 に答える 6

5

First converts the IntPtr to a void pointer. Then to a byte pointer. This is unsafe code.

More on unsafe code: http://msdn.microsoft.com/en-us/library/aa288474%28VS.71%29.aspx

As Robert Harvey notes, a pointer is a memory location. In C/C++ arrays are closely tied to this concept. When it does the square brackets, its basically is adjusting the address.

于 2009-10-30T02:44:08.247 に答える
4

あなたの質問は、コードが何をしているのかを尋ねているように聞こえますが、いくつかのコメントに基づいて、なぜ最初にvoidポインターにキャストしているのかを理解していると思います。

Scan0を最初にvoid*にキャストする理由がないため、ここで混乱する可能性があります。バイト*へのキャストも同様に機能します。

于 2009-10-30T03:00:19.837 に答える
2

IntPtr には、void* へのキャストを可能にする明示的な演算子 (void*) があります。IntPtr から別のものに直接キャストしようとすると、IntPtr クラスには void* キャストのみが定義されているため、コンパイラは barf を実行します。IntPtr::ToPointer( ) も参照してください。

void* から byte* へのキャストはコンパイラーによって許可されています。これは、この時点で自分が何をしているのかわからないと、すでに問題が発生しているためです。

于 2010-04-03T19:34:33.337 に答える
1

It looks bizarre but then I don't know C# that well. It may be that there's some problem with casting a System.IntPtr directly to a byte*, but not with System.IntPtr to void* or void* to byte*.

The end result is probably the same as if you cast int* to char* in C: the ability to derefence p to get a single byte of the integer (assuming CHAR_BIT is 8 in the C implementation).

于 2009-10-30T02:44:38.237 に答える
1

Check out this tutorial on unsafe code. It will explain what the line of code means, and how it can be used for other types besides byte:

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

Essentially, unsafe code allows you to use c-style pointers.

于 2009-10-30T02:46:44.317 に答える
0

voidオブジェクトが自己キャストコードを実行するのを避けるために、キャストする必要がある可能性はありますか?

于 2009-11-05T21:48:31.417 に答える