2017-12-14 4 views
0

다음과 같은 코드가 있습니다 (SharpDX.WIC/SharpDX.Direct3D11 사용). 액세스 위반이 있다는 예외를 항상 throw합니다.혼합 코드에서 액세스 위반의 원점 찾기

public static SharpDX.Direct3D11.Texture2D CreateTexture2DFromBitmap(SharpDX.Direct3D11.Device device, BitmapSource bitmapSource) 
{ 
    // Allocate DataStream to receive the WIC image pixels 

    int stride = PixelFormat.GetStride(bitmapSource.PixelFormat, bitmapSource.Size.Width); 
    using (var buffer = new DataStream(bitmapSource.Size.Height * stride, true, true)) 
    { 
     // Copy the content of the WIC to the buffer 
     bitmapSource.CopyPixels(stride, buffer); 
     return new SharpDX.Direct3D11.Texture2D(device, new SharpDX.Direct3D11.Texture2DDescription() 
     { 
      Width = bitmapSource.Size.Width, 
      Height = bitmapSource.Size.Height, 
      ArraySize = 1, 
      BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource, 
      Usage = SharpDX.Direct3D11.ResourceUsage.Default, 
      CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None, 
      Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm, 
      MipLevels = 1, 
      OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None, 
      SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), 
     }, new DataRectangle(buffer.DataPointer , stride)); 
    } 
} 

예외 메시지는 다음과 같습니다 MyApp.exe의에서 0x00007FF894ECA25C (combase.dll)에서 발생

예외 :가 0xc0000005 : 액세스 위반 쓰기 위치 0x0000000000000008은.

편집는 : MyApp.exe의에서 0x00007FF8825283BD (WindowsCodecs.dll)에서 발생

예외 :가 0xc0000005 : 액세스 위반 읽기 위치 내지 0xFFFFFFFFFFFFFFFF 가끔은 대신이 예외를 얻을.

이 라인에서 발생

bitmapSource.CopyPixels(stride, buffer); 

내가 그렇게 잘못 읽기에서 버퍼 결과에 복사하기 전에이를 처분의 FormatConverter 모든 구성 요소가 필요하다는 어딘가에 읽었다. 그 후에 그것은 효과가 있었지만 아무런 의미있는 이유없이 다시 망가졌습니다. 이제는 항상이 쓰기 액세스 위반이 발생하고 소스를 찾을 수 없습니다.

나는 해체를 사용하여 어디에서 발생했는지 알아 내려고했지만, 0xC0000005이 어디에 배치 될지 전혀 모른다. 결국 이것이 왜 작동하지 않는지 모르겠다. 이 코드는 Stackoverflow 에서조차 많이 참조 된 SharpDX 샘플 코드에서 나온 것입니다. 그러나 그것은 단순히 작동하지 않습니다. FileStream의 기본 내용은 ReadWrite -access이고 DataStream은 읽기 및 쓰기 작업을 허용하도록 설정되어 있습니다.

이것이 SharpDX.WIC 코드베이스의 문제 일 수 있습니까?

간결하고 편리하게 사용하려면 here이 연대순 호출 순서의 전체 소스입니다.

+1

이렇게하면 관리되지 않는 코드가 실패하는 방식입니다. 당신이 정말로 알고있는 모든 것은 그것이 실패한 쓰기 였기 때문에 누군가가 그 DataStream의 기본 저장소에 잘못되었다는 것입니다. 널 포인터에서 8 힌트의 주소 인 0xFF..FF는 훨씬 더 이상하지 않으며 무작위 포인터를 암시합니다. 종종이 특정 코드와 관련이 없으므로 이전 코드로 인한 메모리 손상이 일반적인 트리거입니다. 이것이 디버그하기가 매우 어렵다는 것이 관리 코드가 대중화 된 주된 이유입니다. Application Verifier가 도움이 될 수 있습니다. –

+0

[기본 코드에서 오는 AccessViolationException을 디버깅하는 방법] (https://stackoverflow.com/questions/3245185/how-to-debug-accessviolationexception-coming-from-native-code) –

답변

0

내 생각에 일부 숫자는 포인터와 충돌합니다. 메모리 봐 자사의 액세스하려는 주소 :

  • 0x0000000000000008
  • 내지 0xFFFFFFFFFFFFFFFF

를 정수 형태로,이 8 -1이며, 경우에 그것은 나를 놀라게하지 않을 수 있도록 코드에있는 사람 API가 IntPtr 등을 기대하는 경우 수치 값을 전달합니다. 필자는 작업중인 특정 라이브러리에 대한 액세스 권한이 없지만 인수 유형이 무엇인지 자세히 살펴보고 예상치 못한 것을 전달하지 않도록합니다 (또는 -1 또는 8의 값을 전달할 위치).

+0

의 가능한 복제본이 메서드의 서명은 다음과 같습니다. 'BitmapSource.CopyPixels (int stride, DataPointer dataPointer)'-'DataPointer'는 암시 적으로 버퍼 자체입니다. SharpDX 측에 문제가있는 것 같아서 Github의 Issue 페이지에 검증을 위해 전달할 것입니다 ... 결국 나는 그들에 의해 제공된 샘플 코드를 사용했습니다. – SharpShade

관련 문제