简短的问题:
为什么我在析构函数中的IWICImagingFactory对象的Locals窗口中看到了这个?
长篇解释:
我在CreateDeviceIndependentResources()函数中创建了一个IWICImagingFactory对象:
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&mpWICFactory)
);
}
我在此之后检查过hr,它总是S_OK。
然后在我的CreateDeviceResources()函数中,我在调用LoadBitmapFromFile()时传递一个指向IWICImagingFactory对象的指针:
if(SUCCEEDED(hr))
{
hr = LoadBitmapFromFile(
mpRenderTarget,
mpWICFactory,
L".\\background.png",
0,
0,
&mpBackgroundBitmap);
}
LoadBitmapFromFile函数与MSDN示例中显示的完全相同。您可以在此处查看大部分代码:http://msdn.microsoft.com/en-us/library/dd756686%28v=VS.85%29.aspx
LoadBitmapFromFile()的返回码是S_OK。我现在有一个ID2D1Bitmap对象可以正常工作。
我不会将WIC工厂用于其他任何事情。当我尝试使用SafeRelease()WIC工厂时,我的析构函数会出现问题:
SafeRelease(&mpWICFactory);
SafeRelease()定义为:
template<class Interface>
inline void SafeRelease(Interface** ppInterfaceToRelease)
{
if(*ppInterfaceToRelease != NULL)
{
(*ppInterfaceToRelease)->Release();
(*ppInterfaceToRelease) = NULL;
}
}
在析构函数中,如果我在Locals窗口中展开mpWICFactory对象,我会看到“CXX0030:错误:无法计算表达式”错误。下面的屏幕截图显示了在WICFactory对象上调用SafeRelease()之前的Locals窗口。
http://img21.imageshack.us/img21/9820/localsy.jpg
然后我收到一个错误: Program.exe中0x00d22395处的未处理异常:0xC0000005:访问冲突读取位置0x6df128f0。
这个问题的原因是什么?
编辑:这是一个完整的简单程序,展示了这个问题:
Test.h
#ifndef TEST_H
#define TEST_H
#include <Windows.h>
#include <wincodec.h>
#include <d2d1.h>
class Test
{
public:
IWICImagingFactory *mpWICFactory;
Test();
~Test();
HRESULT Init();
};
template<class Interface>
inline void SafeRelease(Interface** ppInterfaceToRelease)
{
if(*ppInterfaceToRelease != NULL)
{
(*ppInterfaceToRelease)->Release();
(*ppInterfaceToRelease) = NULL;
}
}
#endif
Test.cpp的
#include "Test.h"
Test::Test() : mpWICFactory(NULL)
{
}
Test::~Test()
{
SafeRelease(&mpWICFactory);
}
HRESULT Test::Init()
{
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&mpWICFactory)
);
return hr;
}
Main.cpp的
#include <Windows.h>
#include "Test.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
PSTR cmdLine, int showCmd)
{
if(SUCCEEDED(CoInitialize(NULL)))
{
Test app;
app.Init();
CoUninitialize();
}
return 0;
}
答案 0 :(得分:3)
短答案是虚函数指针0x6df128e8
无效,因此调试器无法取消引用它。这就是“表达无法评估”的含义。
因此,当程序稍后尝试调用其中一个虚函数时,指针仍然不起作用,并且您获得访问冲突。
长而硬部分,如果找到您的对象被无效值覆盖的具体位置。不幸的是,它几乎可以在程序的任何其他地方......
答案 1 :(得分:0)
尝试在初始化后立即调用SafeRelease()
,看看它是否有效。
另外,尝试显式调用清理(使用某种uninitialize函数)而不是在析构函数中执行此操作。当您将清理工作留给析构函数时,有时您无法完全控制正在清理的内容。
也可能是你以错误的顺序销毁了一些依赖对象。