2011-10-03 143 views
1

簡短的問題:CXX0030:錯誤:表達式無法計算

爲什麼我看到這個在本地窗口爲我IWICImagingFactory對象,而在我的析構函數?

長解釋:

我創造我的CreateDeviceIndependentResources一個IWICImagingFactory對象()函數:

if (SUCCEEDED(hr)) 
{ 
    hr = CoCreateInstance(
     CLSID_WICImagingFactory, 
     NULL, 
     CLSCTX_INPROC_SERVER, 
     IID_PPV_ARGS(&mpWICFactory) 
     ); 
} 

我已經在這之後檢查小時,它始終是S_OK。

然後在我CreateDeviceResources()函數我將指針傳遞到IWICImagingFactory對象中LoadBitmapFromFile()的調用:

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; 
} 

} 

雖然在析構函數,如果我擴大在mpWICFactory對象本地窗口,我看到「CXX0030:錯誤:表達式無法評估」錯誤。下面的截圖顯示了在調用WICFactory對象上的SafeRelease()之前的Locals窗口。

http://img21.imageshack.us/img21/9820/localsy.jpg

然後我得到一個錯誤:在的Program.exe 0x00d22395 未處理的異常:0000005:訪問衝突讀取位置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

如何定義mpWICFactory? –

+0

IWICImagingFactory * mpWICFactory; 我在構造函數初始值設定項列表中將它初始化爲NULL。 – user974967

回答

0

嘗試在初始化後立即調用SafeRelease(),看看它是否工作。

此外,請嘗試顯式調用清理(使用某種類型的uninitialize函數),而不是在析構函數中執行此操作。當您將清理工作留給析構函數時,有時您無法完全控制何時清理的內容。

它也可能是你以錯誤的順序銷燬一些依賴對象。

+0

初始化後立即調用SafeRelease(),虛擬函數指針仍然有效。我也嘗試調用一個Uninitialize()函數(在去析構函數之前)並且它工作正常。我在上面發佈了一個修改後的程序,這是唯一的對象,所以我不認爲這個問題的順序是分項對象。 – user974967

+0

在您的應用程序對象被銷燬之前,您正在調用'CoUninitialize' **。嘗試使用'new'和'delete'顯式創建和銷燬'Test'對象。 –

+0

謝謝!好眼睛! :) – user974967

3

簡短的回答是虛函數指針0x6df128e8是無效的,所以調試器無法取消對它的引用。這就是「表達無法評估」的意思。

因此,當程序稍後嘗試調用其中一個虛擬函數時,指針仍然不起作用,並且會出現訪問衝突。

long and hard部分如果找出對象被無效值覆蓋的確切位置。不幸的是,它可以在程序中的其他任何地方...

+0

我已編輯帖子以包含一個完整的簡單程序來演示此問題。 – user974967