gpt4 book ai didi

c++ - 在析构函数中调用 Inherited IUnknown::Release()

转载 作者:行者123 更新时间:2023-11-30 00:57:39 26 4
gpt4 key购买 nike

为什么在析构函数中对 IWICImagingFactory 对象调用继承的 IUnknown::Release() 函数会导致“CXX0030:错误:无法计算表达式”显示在对象的虚函数表 (__vfptr) 中的每个条目?

这是引用我之前发布的一个问题,但后来我意识到问题只发生在析构函数中。虚函数表在我检查过的其他任何地方都有效。但是,在析构函数中,所有条目都显示为 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。

最佳答案

我最近也在为这个问题苦苦挣扎。问题在于,IWICImagingFactory 的创建和释放分别取决于之前和之后调用的 CoInitialize/CoUninitialize。在您的应用程序中,很可能在析构函数中释放 IWICImagingFactory 之前调用了 CoUninitialize(),这会导致崩溃。请注意,ID2D1RenderTarget 等似乎不受影响,在调用 CoUninitialize() 后仍可释放。

RunMessageLoop() 或任何地方删除对 CoUninitialize() 的调用,并将其放在析构函数中的释放调用之后,崩溃应该就会消失。

关于c++ - 在析构函数中调用 Inherited IUnknown::Release(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7632066/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com