이 c# 코드를 설명하십시오 : 바이트*p = (바이트*) (void*) 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
a void
바늘. 그런 다음 a byte
바늘. 이것은 unsafe
암호.
안전하지 않은 코드에 대한 자세한 내용 :http://msdn.microsoft.com/en-us/library/aa288474%28vs.71%29.aspx
Robert Harvey가 지적한 것처럼 포인터는 메모리 위치입니다. C/C ++에서 배열은이 개념과 밀접하게 연결되어 있습니다. 사각형 브래킷을 사용하면 기본적으로 주소를 조정합니다.
다른 팁
당신의 질문은 마치 당신이 묻는 것처럼 들립니다 무엇 코드는 수행 중이지만 귀하의 의견 중 일부를 기반으로합니다. 왜 먼저 공허 포인터로 캐스팅됩니다.
Scan0을 먼저 공허*에 캐스팅 할 이유가 없기 때문에 여기서 혼란 스러울 것입니다. 바이트에 대한 캐스트도 작동합니다.
intptr에는 명시 적 연산자 (void*)가있어 캐스팅이 void*를 허용합니다. intptr에서 다른 것에 직접 캐스트하려고하면 void* 캐스트 만 intptr 클래스에 대해 정의되므로 컴파일러가 바프가됩니다. intptr :: topointer ()도 참조하십시오.
void*에서 바이트*로 캐스팅하는 것은 컴파일러에 의해 허용됩니다.이 시점에서 당신이 무엇을하고 있는지 모른다면 이미 당신은 이미 곤경에 처해 있습니다.
기괴한 것처럼 보이지만 C#을 잘 모릅니다. 그것 5월 캐스팅에 약간의 문제가 있습니다 System.IntPtr
직접 a byte*
, 그러나 그렇지는 않습니다 System.IntPtr
에게 void*
또는 void*
에게 byte*
.
최종 결과는 아마도 캐스트와 동일합니다. int*
에게 char*
C : 혼란스러운 능력 p
정수의 단일 바이트를 얻으려면 (CHAR_BIT가 C 구현에서 8이라고 가정).
안전하지 않은 코드 에서이 자습서를 확인하십시오. 코드 라인의 의미와 바이트 외에 다른 유형에 어떻게 사용할 수 있는지 설명합니다.
http://msdn.microsoft.com/en-us/library/aa288474(vs.71).aspx
기본적으로 안전하지 않은 코드를 사용하면 C 스타일 포인터를 사용할 수 있습니다.
캐스팅해야 할 가능성이 있습니까? void
객체가 셀프 캐스트 코드를 실행하는 것을 피하려면?