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

首先将 转换IntPtrvoid指针。然后指向一个byte指针。这是unsafe代码。

有关不安全代码的更多信息:http: //msdn.microsoft.com/en-us/library/aa288474%28VS.71%29.aspx

正如 Robert Harvey 所说,指针是一个内存位置。在 C/C++ 中,数组与这个概念密切相关。当它做方括号时,它基本上是在调整地址。

于 2009-10-30T02:44:08.247 回答
4

您的问题听起来好像您在问代码在做什么,但是根据您的一些评论,我认为您在追问为什么它首先要转换为 void 指针。

您可能在这里感到困惑,因为没有理由首先将 Scan0 转换为 void*。转换为 byte* 也可以。

于 2009-10-30T03:00:19.837 回答
2

IntPtr 有一个显式运算符 (void*),它允许强制转换为 void*。如果您尝试直接从 IntPtr 强制转换为其他内容,编译器将会出错,因为只有 void* 强制转换是为 IntPtr 类定义的。另见 IntPtr::ToPointer()。

编译器允许从 void* 转换为 byte* ,因为此时如果您不知道自己在做什么,那么您已经遇到了麻烦。

于 2010-04-03T19:34:33.337 回答
1

它看起来很奇怪,但我不太了解 C#。将 a直接转换为 a可能存在一些问题,而不是to或to 。System.IntPtrbyte*System.IntPtrvoid*void*byte*

最终结果可能与您在 C 中转换为相同:取消引用以获取整数的单个字节的能力int*(假设 CHAR_BIT 在 C 实现中为 8)。char*p

于 2009-10-30T02:44:38.237 回答
1

查看有关不安全代码的本教程。它将解释这行代码的含义,以及它如何用于除字节之外的其他类型:

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

本质上,不安全代码允许您使用 c 风格的指针。

于 2009-10-30T02:46:44.317 回答
0

您是否可能需要强制转换void以避免对象在其上执行一些自转换代码?

于 2009-11-05T21:48:31.417 回答