デストラクタのIWICImagingFactoryオブジェクトで継承されたIUnknown::Release()関数を呼び出すと、オブジェクトの仮想関数テーブル(__vfptr)の各エントリに「CXX0030:エラー:式を評価できません」と表示されるのはなぜですか?
これは私が投稿した以前の質問を参照していますが、問題はデストラクタでのみ発生することに気づきました。仮想関数テーブルは、私がチェックした他の場所で有効に見えます。ただし、デストラクタに入ると、すべてのエントリがCXX0030エラーで表示され、継承されたIUknown :: Release()を呼び出そうとして失敗します。
編集:ここに示すためのいくつかのコードがあります:
HRESULT DemoApp::CreateDeviceIndependentResources()
{
HRESULT hr;
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &mpDirect2DFactory);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&mpWICFactory)
);
}
//CoCreateInstance returns S_OK.
//Other unrelated code here.
}
HRESULT DemoApp::CreateDeviceResources()
{
HRESULT hr;
//Other unrelated code here for creating device-dependant resources.
//mpBackgroundBitmap is a ID2D1Bitmap*.
if(SUCCEEDED(hr))
{
hr = LoadBitmapFromFile(
mpRenderTarget,
mpWICFactory,
L".\\background.png",
0,
0,
&mpBackgroundBitmap);
}
}
//The below LoadBitmapFromFile() code is taken directly from an MSDN sample.
//I didn't write it.
HRESULT DemoApp::LoadBitmapFromFile(
ID2D1RenderTarget *pRenderTarget,
IWICImagingFactory *pIWICFactory,
PCWSTR uri,
UINT destinationWidth,
UINT destinationHeight,
ID2D1Bitmap **ppBitmap
)
{
IWICBitmapDecoder *pDecoder = NULL;
IWICBitmapFrameDecode *pSource = NULL;
IWICStream *pStream = NULL;
IWICFormatConverter *pConverter = NULL;
IWICBitmapScaler *pScaler = NULL;
HRESULT hr = pIWICFactory->CreateDecoderFromFilename(
uri,
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
if (SUCCEEDED(hr))
{
// Create the initial frame.
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// Convert the image format to 32bppPBGRA
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = pIWICFactory->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
// If a new width or height was specified, create an
// IWICBitmapScaler and use it to resize the image.
if (destinationWidth != 0 || destinationHeight != 0)
{
UINT originalWidth, originalHeight;
hr = pSource->GetSize(&originalWidth, &originalHeight);
if (SUCCEEDED(hr))
{
if (destinationWidth == 0)
{
FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);
destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
}
else if (destinationHeight == 0)
{
FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);
destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
}
hr = pIWICFactory->CreateBitmapScaler(&pScaler);
if (SUCCEEDED(hr))
{
hr = pScaler->Initialize(
pSource,
destinationWidth,
destinationHeight,
WICBitmapInterpolationModeCubic
);
}
if (SUCCEEDED(hr))
{
hr = pConverter->Initialize(
pScaler,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
}
}
else // Don't scale the image.
{
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
}
if (SUCCEEDED(hr))
{
// Create a Direct2D bitmap from the WIC bitmap.
hr = pRenderTarget->CreateBitmapFromWicBitmap(
pConverter,
NULL,
ppBitmap
);
}
SafeRelease(&pDecoder);
SafeRelease(&pSource);
SafeRelease(&pStream);
SafeRelease(&pConverter);
SafeRelease(&pScaler);
return hr;
}
//Now I call SafeRelease() in my destructor and the virtual function table entires are showing the error.
DemoApp::~DemoApp()
{
SafeRelease(&mpDirect2DFactory);
SafeRelease(&mpWICFactory); //here is the problem apparently
SafeRelease(&mpDWriteFactory);
SafeRelease(&mpRenderTarget);
SafeRelease(&mpBackgroundBitmap);
}
//SafeRelease is defined as:
template<class Interface>
inline void SafeRelease(Interface** ppInterfaceToRelease)
{
if(*ppInterfaceToRelease != NULL)
{
(*ppInterfaceToRelease)->Release();
(*ppInterfaceToRelease) = NULL;
}
}
問題は、WICFactoryオブジェクトでSafeRelease()を呼び出すと、次のようになります。DemoApp.exeの0x0024e135でのファーストチャンス例外:0xC0000005:アクセス違反の読み取り場所0x6d5c28f0。DemoApp.exeの0x0024e135で未処理の例外:0xC0000005:アクセス違反の読み取り場所0x6d5c28f0。