###前提・実現したいこと
Direct2Dで画像を読み込んで描画するという処理を書いています。
WICを利用して画像を読み込み、ID2D1Bitmapを生成して、
ID2D1HwndRenderTargetのdrawBitmapで描画する
といった感じで画像の描画はできました。
しかし、ID2D1BitmapのReleaseを行うときに強制終了してします。
なんとかして強制終了をさせずに終了させたいです。
###発生している問題・エラーメッセージ
例外がスローされました:読み取りアクセス違反。 this->wicImagingFactory-> が 0x6D211E90 でした。
###該当のソースコード
7/4更新
(実際はファイルを分けてコードを書いてあります。)
C++
1#include <d2d1.h> 2#include <wincodec.h> 3#include <map> 4 5#pragma comment(lib, "d2d1.lib") 6#pragma comment(lib, "dxguid.lib") 7#pragma comment(lib, "windowscodecs.lib") 8 9// ウィンドウの幅 10extern int WINDOW_WIDTH; 11 12// ウィンドウの高さ 13extern int WINDOW_HEIGHT; 14 15// アプリケーションのインスタンスハンドル 16extern HINSTANCE applicationInstance; 17 18// ウィンドウハンドル 19extern HWND windowHandle; 20 21// Direct2Dファクトリ 22ID2D1Factory*direct2DFactory = NULL; 23 24// レンダーターゲット 25ID2D1HwndRenderTarget* renderTarget = NULL; 26 27// ブラシ 28ID2D1SolidColorBrush* brush = NULL; 29 30// Direct2Dの初期化処理を行う 31void initializeDirect2D() 32{ 33 // Direct2Dファクトリを生成する 34 D2D1CreateFactory( 35 D2D1_FACTORY_TYPE_SINGLE_THREADED, 36 &direct2DFactory); 37 38 // レンダーターゲットを生成する 39 direct2DFactory->CreateHwndRenderTarget( 40 D2D1::RenderTargetProperties(), 41 D2D1::HwndRenderTargetProperties( 42 windowHandle, 43 D2D1::SizeU(WINDOW_WIDTH, WINDOW_HEIGHT)), 44 &renderTarget); 45 46 // ブラシを生成する 47 renderTarget->CreateSolidColorBrush(D2D1::ColorF(0, 0, 0), &brush); 48} 49 50// Direct2Dの終了処理を行う 51void finalizeDirect2D() 52{ 53 OutputDebugString("brushをReleaseします!\n"); 54 if (brush != NULL) 55 brush->Release(); 56 OutputDebugString("renderTargetをReleaseします!\n"); 57 if (renderTarget != NULL) 58 renderTarget->Release(); 59 OutputDebugString("direct2DFactoryをReleaseします!\n"); 60 if (direct2DFactory != NULL) 61 direct2DFactory->Release(); 62} 63 64class Image 65{ 66public: 67 Image(const wchar_t*); 68 ~Image(); 69 void draw(float x, float y); 70 71private: 72 IWICImagingFactory* wicImagingFactory = NULL; 73 IWICBitmapDecoder* wicBitmapDecoder = NULL; 74 IWICBitmapFrameDecode* wicBitmapFrame = NULL; 75 IWICFormatConverter* wicFormatConverter = NULL; 76 ID2D1Bitmap* bitmap = NULL; 77}; 78 79Image::Image(const wchar_t* fileName) 80{ 81 // WICイメージングファクトリを生成する 82 CoCreateInstance( 83 CLSID_WICImagingFactory, 84 NULL, 85 CLSCTX_INPROC_SERVER, 86 IID_IWICImagingFactory, 87 (LPVOID*)&wicImagingFactory); 88 89 // Bitmapデコーダを生成する 90 wicImagingFactory->CreateDecoderFromFilename( 91 fileName, 92 NULL, 93 GENERIC_READ, 94 WICDecodeMetadataCacheOnLoad, 95 &wicBitmapDecoder); 96 97 // 画像からフレームを読み込む 98 wicBitmapDecoder->GetFrame(0, &wicBitmapFrame); 99 100 // フォーマットコンバータを生成する 101 wicImagingFactory->CreateFormatConverter(&wicFormatConverter); 102 103 // コンバータの初期化をする 104 wicFormatConverter->Initialize( 105 wicBitmapFrame, 106 GUID_WICPixelFormat32bppPBGRA, 107 WICBitmapDitherTypeNone, 108 NULL, 109 0, 110 WICBitmapPaletteTypeCustom); 111 112 // Bitmapを生成する 113 renderTarget->CreateBitmapFromWicBitmap( 114 wicFormatConverter, 115 NULL, 116 &bitmap); 117} 118 119Image::~Image() 120{ 121 OutputDebugString("bitmapをReleaseします!\n"); 122 if (bitmap != NULL) 123 bitmap->Release(); 124 OutputDebugString("wicFormatConverterをReleaseします!\n"); 125 if (wicFormatConverter != NULL) 126 wicFormatConverter->Release(); 127 OutputDebugString("wicBitmapFrameをReleaseします!\n"); 128 if (wicBitmapFrame != NULL) 129 wicBitmapFrame->Release(); 130 OutputDebugString("wicBitmapDecoderをReleaseします!\n"); 131 if (wicBitmapDecoder != NULL) 132 wicBitmapDecoder->Release(); 133 OutputDebugString("wicImagingFactoryをReleaseします!\n"); 134 if (wicImagingFactory != NULL) 135 wicImagingFactory->Release(); 136} 137 138void Image::draw(float x, float y){}
C++
1int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 2{ 3 // ウィンドウを生成する 4 initializeWin32API(); 5 6 // Direct2Dの初期化処理を行う 7 initializeDirect2D(); 8 9 // DirectInputの初期化処理を行う 10 initializeDirectInput(); 11 12 Image* image = new Image(L"hoge.png"); 13 14 // 終了メッセージが送られるまでループする 15 while (checkMessage()) 16 { 17 beginRendering(); 18 19 clearScreen(1, 1, 1); 20 image->draw(0, 0); 21 22 endRendering(); 23 } 24 25 delete image; 26 27 // Direct2Dの終了処理を行う 28 finalizeDirect2D(); 29 30 // DirectInputの終了処理を行う 31 finalizeDirectInput(); 32 33 return 0; 34}
###試したこと
Release行う順番が良くないかと思い、
bitmapのReleaseを最初に行うように変更してみましたが、
アクセス違反が発生していました。
7/4追記
別のマシンでコンパイル・実行したところ
特に強制終了することなく動作しました。
マシンA … 最初に試したマシン => コンパイル・実行 => 実行時に強制終了
マシンB … 次に試したマシン => コンパイル・実行 => 異常なし
マシンC … その次に試したマシン => マシンAとマシンBでビルドしたexeを実行 => どちらも異常なし
マシンD … その後試したマシン => マシンAとマシンBでビルドしたexeを実行 => どちらも実行時に強制終了
その後マシンAを再起動させてもう一度コンパイル・実行したところ
実行時に強制終了してしまいました。
###補足情報(言語/FW/ツール等のバージョンなど)
Visual Studio Commnunity 2015
Direct2D (d2d1.h) (d2d1.lib) (dxguid.lib)
WIC (wincodec.h) (windowscodecs.lib)
マシンA (Windows 7 Ultimate x64)
マシンB (Windows 10 Pro x64)
マシンC (Windows 10 Home x86)
マシンD (Windows 7 Professional x64)
###解決策 (by catsforepawさん)
CoInitializeとCoUninitializeを呼ぶようにする。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/07/04 06:25
2016/07/04 12:06
2016/07/04 13:24
2016/07/04 13:52