解释此C#代码:字节* P =(字节*)(无效*)SCAN0;
-
22-07-2019 - |
题
我发现从网的代码中,我无法理解此行: -
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;
解决方案
首先转换IntPtr
到void
指针。然后到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.IntPtr
到byte*
,但不能与System.IntPtr
到void*
或void*
到byte*
。
最终结果可能是相同的,如果你施放int*
在C char*
:以反引用p
以获得整数的一个字节的能力(假设CHAR_BIT 8是在C实现)
查核上不安全代码本教程。这将解释的代码行装置,以及如何可以用于其它类型的除字节:
http://msdn.microsoft.com/ EN-US /库/ aa288474(VS.71)的.aspx
基本上,不安全代码允许您使用c样式指针。
有没有可能,你需要转换为void
,以避免它执行一些自投代码的对象?