2012-08-03 4 views
0

.NET에서 일부 이미지 조작을하고 있습니다 (VB 2010). 'foo는'참조 (LockBits (DirectShow webcam)로 메모리가 손상되었습니다.

Sub Manipulate(IMG As Bitmap) 
    ' Dim foo(100000) As Integer - will need it later... 

    Dim bd = IMG.LockBits(New Rectangle(0, 0, IMG.Width, IMG.Height), 
          Imaging.ImageLockMode.ReadWrite, 
          Imaging.PixelFormat.Format24bppRgb) 
    Dim absstride = Math.Abs(bd.Stride) 
    Dim numbytes = absstride * IMG.Height 
    Dim bytes(numbytes - 1) As Byte 
    Dim flipped = bd.Stride < 0 
    Dim ptr = If(flipped, bd.Scan0 - numbytes + absstride, bd.Scan0) 
    System.Runtime.InteropServices.Marshal.Copy(ptr, bytes, 0, numbytes) 

    ' I'm going to put sg here 

    System.Runtime.InteropServices.Marshal.Copy(bytes, 0, ptr, numbytes) 
    IMG.UnlockBits(bd) 
End Sub 

이 간단한 목적을 위해 완벽하게 작동하지만, 내 알고리즘은 몇 가지 큰 변수가 필요합니다 (예 : 이미지를 밝게.) : 나는 (아직 아무것도하지 않음) 다음 코드를 사용하고 있습니다 위). 를 선언 할 때 (해당 행의 주석을 해제), 갑자기 예외를 얻을 :
를 '갑'의 크기에 따라 ...

이 ... 중 첫 번째 Marshal.Copy은()
AccessViolationException 예외 : 읽기 시도 또는 쓰기 방지 된 메모리. 이것은 종종 다른 메모리가 손상되었다는 표시입니다.

... 'bytes'가 선언되었습니다.
FatalExecutionEngineError : 런타임에 치명적인 오류가 발생했습니다. 오류 주소는 0x6819d142, 0x3690 스레드에있었습니다. 오류 코드는 0xc0000005입니다. 이 오류는 CLR 또는 안전하지 않거나 확인할 수없는 사용자 코드 부분의 버그 일 수 있습니다. 이 버그의 일반적인 출처에는 스택을 손상시킬 수있는 COM-interop 또는 PInvoke의 사용자 마샬링 오류가 포함됩니다.

... 예외가 없거나 전혀 작동하지 않아 정상적으로 작동합니다.

무슨 일입니까?

추가 정보 : 웹캠에서 DirectShow를 사용하여 이미지 개체를 가져옵니다.

+0

뒤집기를 제거하면 비트 맵이 Scan0 이전에 시작되지 않습니다. 그리고 더 이상 실행되지 않는 콜백에서 얻은 비트 맵에서이 코드를 실행하지 마십시오. 비트 맵 (이미지) 생성자로 비트 맵의 ​​전체 복사본을 만드는 경우가 아니면. –

+0

@HansPassant 나는 이론 상으로는 항상 Scan0으로부터 복사해야한다는 것을 알고 있지만, 뒤집 으면 true로 작동하지 않을 것이다. 이 방식으로 올바른 메모리 위치에서 복사 한 후 Bitmap.GetPixel()을 사용하여 체크합니다. – Dave

+0

@HansPassant 깊은 사본을 작성하면 문제가 해결됩니다. – Dave

답변

0

한스 (Hans)가 지적했듯이 비트 맵의 ​​전체 복사본을 만들어야 만 모든 것이 작동합니다. 그렇지 않으면 이미 처분 된 이미지를 사용하고 있습니다. 이것은 처분 된 메모리를 사용하는 몇 가지 큰 변수를 선언 할 때까지 침묵하는 오류입니다. GC가 겉으로보기에 임의의 오류를 던지는 경우입니다.