我发现从网的代码中,我无法理解此行: -

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

有SCAN0是的 System.IntPtr。 这是C#.NET代码。 PLZ解释上面的行。

的完整代码在下面给出。这是代码的图像转换以灰度显示。

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;
有帮助吗?

解决方案

首先转换IntPtrvoid指针。然后到byte指针。这是unsafe代码。

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

正如罗伯特哈维注意到,一个指针是一个存储器位置。在C / C ++阵列紧密联系在一起的这个概念。当它的方括号中,它基本上被调整的地址。

其他提示

您的问题听起来就好像你问的什么的代码是干什么的,但基于一些您的意见,我认为你是后的为什么的是第一投射到空指针。

您有可能在这里感到困惑,因为没有理由第一投射SCAN0为void *。演员以字节*会很好的工作。

IntPtr的具有显式操作者(无效*),允许浇铸到void *。如果您尝试直接从IntPtr的投别的东西,编译器会BARF因为只有void *的强制转换为IntPtr的类定义的。另见的IntPtr :: ToPointer()。

这是无效*铸造成字节*由编译器允许的,因为在这一点上,如果你不知道你在做什么,你就麻烦了。

看起来怪异,但那时我不知道C#那么好。它的可能的是有一些问题,直接铸造System.IntPtrbyte*,但不能与System.IntPtrvoid*void*byte*

最终结果可能是相同的,如果你施放int*在C char*:以反引用p以获得整数的一个字节的能力(假设CHAR_BIT 8是在C实现)

查核上不安全代码本教程。这将解释的代码行装置,以及如何可以用于其它类型的除字节:

http://msdn.microsoft.com/ EN-US /库/ aa288474(VS.71)的.aspx

基本上,不安全代码允许您使用c样式指针。

有没有可能,你需要转换为void,以避免它执行一些自投代码的对象?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top