I 오류가 일부 코드가 있습니다 다음과 같다lockbits가 필요합니까?
A는 잘못된 기능의 버전을 손질 "AccessViolationException 사용자 코드에 의해 처리되지 않은했다가 ... 보호 된 메모리를 읽거나 쓰려고했습니다"
protected override void OnPaint(PaintEventArgs pe)
{
if ((updatingFastBackground) || (Calculating)) return; //ADDED FOR DEBUGGING, SEE BELOW
BitmapData canvasData = Canvas.LockBits(new Rectangle(Point.Empty, Canvas.Size), ImageLockMode.WriteOnly, FastPixelFormat);
BitmapData fbgData = fastBackground.LockBits(new Rectangle(Point.Empty, fastBackground.Size), ImageLockMode.ReadOnly, FastPixelFormat);
try
{
unsafe
{
byte* canvasDataScan0 = (byte*)canvasData.Scan0.ToPointer();
byte* fbgDataScan0 = (byte*)fbgData.Scan0.ToPointer();
Rectangle spriteBounds = new Rectangle(Point.Empty, ButtonImages.ImageSize);
for (int i = 0; i < ButtonImages.Images.Count; i++)
{
// Button offset location
Point l = new Point(
(int)((i % columnCount) * hStep + myIVM.Location.X),
(int)((i/columnCount) * vStep + myIVM.Location.Y));
// Paint at current location?
if (buttonPaintBounds.Contains(l))
{
BitmapData spriteData = buttonBitmaps[i].LockBits(spriteBounds, ImageLockMode.ReadOnly, FastPixelFormat);
try
{
int spriteLeft = Math.Max(l.X, 0);
int spriteRight = Math.Min(l.X + ButtonImages.ImageSize.Width, canvasData.Width);
int spriteTop = Math.Max(l.Y, 0);
int spriteBottom = Math.Min(l.Y + ButtonImages.ImageSize.Height, canvasData.Height);
int spriteWidth = spriteRight - spriteLeft;
int spriteHeight = spriteBottom - spriteTop;
byte* canvasRowLeft = canvasDataScan0 + (spriteTop * canvasData.Stride) + spriteLeft * 4;
byte* spriteRowLeft =
(byte*)spriteData.Scan0.ToPointer() +
Math.Max((spriteTop - l.Y), 0) * spriteData.Stride +
Math.Max((spriteLeft - l.X), 0) * 4;
for (int y = 0; y < spriteHeight; y++)
{
canvasRowLeft += canvasData.Stride;
spriteRowLeft += spriteData.Stride;
Byte* canvasWalk = (Byte*)canvasRowLeft;
Byte* spriteWalk = (Byte*)spriteRowLeft;
for (int x = 0; x < spriteWidth; x++)
{
if (spriteWalk[3] != 255)
{
canvasWalk[0] = (byte)(canvasWalk[0] * spriteWalk[3]/255 + spriteWalk[0]);
canvasWalk[1] = (byte)(canvasWalk[1] * spriteWalk[3]/255 + spriteWalk[1]);
canvasWalk[2] = (byte)(canvasWalk[2] * spriteWalk[3]/255 + spriteWalk[2]);
}
canvasWalk += 4;
spriteWalk += 4;
}
}
thesePoints.Add(l);
}
finally
{
buttonBitmaps[i].UnlockBits(spriteData);
}
}
canvasWalk[0] = 0;
: 대체 때에도
canvasWalk[0] = (byte)(canvasWalk[0] * spriteWalk[3]/255 + spriteWalk[0]);
과 :
에러 라인에서 발생
반복 변수 y
과 x
은 충돌 할 때마다 다른 값을 가지므로 외부 함수가 Canvas
비트 맵을 수정한다고 생각합니다.
이것이 실제로 문제가되는 경우 fastBackground
및 Canvas
이 외부에서 수정되는 것을 방지하는 방법이 있습니까? 내가 LockBits
이 그 것을 할 줄 알았는데 ...
을 그 답을하는 것만으로는 충분하지 있다면, 여기에 몇 가지 더 내가 해봤입니다 : 내가 fastBackground
Canvas
또는 경우의 OnPaint를 종료 라인
if ((updatingFastBackground) || (Calculating)) return;
추가 치수가 다른 기능에 의해 수정됩니다.
I 수 (나는 그들이해야합니다 생각하는) 페인트와 같은 시간에 실행되는 비트 맵 fastBackground
및 Canvas
을 수정하는 기능을 방지하기 위해 뮤텍스를 사용하지만 나는 오히려 그들에게 캔버스와 같은 다른 방법을 차단하는 것 공개적이며 클래스에서 뮤텍스를 전달하지 않아도됩니다.
@ usr 님의 제안에 따르면이 버전이 더 이상 작동하지 않습니다 ... PTD 오류 일 수 있습니다. 이 관리되지 않는 메모리이기 때문에
고정이 LockBits에 의해 반환 된 버퍼 필요하지 않습니다 : 그것은 문제를 해결 도움이 때문에 대답에 내 의견을 이동 (너무 바보 프로그래머) 즉 연산 오류
protected override void OnPaint(PaintEventArgs pe)
{
if ((updatingFastBackground) || (Calculating)) return; //ADDED FOR DEBUGGING, SEE BELOW
BitmapData canvasData = Canvas.LockBits(new Rectangle(Point.Empty, Canvas.Size), ImageLockMode.WriteOnly, FastPixelFormat);
BitmapData fbgData = fastBackground.LockBits(new Rectangle(Point.Empty, fastBackground.Size), ImageLockMode.ReadOnly, FastPixelFormat);
try
{
unsafe
{
byte* canvasDataScan0 = (byte*)canvasData.Scan0.ToPointer();
byte* fbgDataScan0 = (byte*)fbgData.Scan0.ToPointer();
Rectangle spriteBounds = new Rectangle(Point.Empty, ButtonImages.ImageSize);
for (int i = 0; i < ButtonImages.Images.Count; i++)
{
// Button offset location
Point l = new Point(
(int)((i % columnCount) * hStep + myIVM.Location.X),
(int)((i/columnCount) * vStep + myIVM.Location.Y));
// Paint at current location?
if (buttonPaintBounds.Contains(l))
{
BitmapData spriteData = buttonBitmaps[i].LockBits(spriteBounds, ImageLockMode.ReadOnly, FastPixelFormat);
try
{
byte* canvasRowLeft = canvasDataScan0;
byte* spriteRowLeft = (byte*)spriteData.Scan0.ToPointer();
for (int y = 0; y < 145; y++)
{
canvasRowLeft += canvasData.Stride;
spriteRowLeft += spriteData.Stride;
Byte* canvasWalk = (Byte*)canvasRowLeft;
Byte* spriteWalk = (Byte*)spriteRowLeft;
for (int x = 0; x < 145; x++)
{
if (spriteWalk[3] != 255)
{
canvasWalk[0] = 0;
canvasWalk[1] = 0;
canvasWalk[2] = 0;
}
canvasWalk += 4;
spriteWalk += 4;
}
}
thesePoints.Add(l);
}
finally
{
buttonBitmaps[i].UnlockBits(spriteData);
}
}
제목에 '고정'이 언급 된 이유는 비트 맵을 편집하는 동안 일부 고정 메모리를 잠그기 위해 '고정'을 사용해야한다는 것입니다. – AppFzx
해결책으로 [고정] (http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx)을 사용해야한다고 가정합니다. 이 경우에 선언문을 안전하지 않게 이동해야합니다 ... – rene
@rene은'byte * canvasDataScan0'과'byte * fbgDataScan0'을 충분하게 만들거나 실제 비트 맵을 고정시키지 않기 때문에 다른 숨겨진 오류를 일으킬 수 있습니까? – AppFzx