CXX0030:错误:无法计算表达式

时间:2011-10-03 00:16:12

标签: c++ visual-studio directx

简短的问题:

为什么我在析构函数中的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;
}

2 个答案:

答案 0 :(得分:3)

答案是虚函数指针0x6df128e8无效,因此调试器无法取消引用它。这就是“表达无法评估”的含义。

因此,当程序稍后尝试调用其中一个虚函数时,指针仍然不起作用,并且您获得访问冲突。

长而硬部分,如果找到您的对象被无效值覆盖的具体位置。不幸的是,它几乎可以在程序的任何其他地方......

答案 1 :(得分:0)

尝试在初始化后立即调用SafeRelease(),看看它是否有效。

另外,尝试显式调用清理(使用某种uninitialize函数)而不是在析构函数中执行此操作。当您将清理工作留给析构函数时,有时您无法完全控制正在清理的内容。

也可能是你以错误的顺序销毁了一些依赖对象。