我正在将应用程序从VC6升级到VS2010(旧版代码)。应用程序在VC6中运行,但在将项目转换为VS2010后,我遇到了一些问题。 在退出应用程序时,程序会在尝试锁定进入关键部分时中断。 锁定计数通常从-1(未锁定)到-2(锁定)交替,但在程序崩溃之前,锁定计数为0.。
g_RenderTargetCriticalSection.Lock();// Breaks here
if (g_RenderTargets.Lookup(this, pRenderTarget))
{
ASSERT_VALID(pRenderTarget);
g_RenderTargets.RemoveKey(this);
delete pRenderTarget;
}
g_RenderTargetCriticalSection.Unlock();
以下是CCriticalSection::Lock()
函数,其中::EnterCriticalSection(&m_sect);
失败。我发现奇怪的是,在失败时,锁定计数从0变为-4 ??
_AFXMT_INLINE BOOL (::CCriticalSection::Lock())
{
::EnterCriticalSection(&m_sect);
return TRUE;
}
如果有人遇到类似的事情,我们将非常感谢您的一些见解。提前谢谢。
答案 0 :(得分:1)
注释表明这是一个文件范围对象析构函数顺序问题。有多种方法可以解决这个问题。由于我还没有看到其他代码,因此很难提供具体的建议,但有一个想法是将CS改为生活在shared_ptr
并让你的CW保留一份副本它不会过早被摧毁。 e.g:
std::shared_ptr<CCriticalSection> g_renderTargetCriticalSection(new CCriticalSection());
然后在你的窗口类中:
class CMyWindow : public CWnd
{
private:
std::shared_ptr<CCriticalSection> m_renderTargetCriticalSection;
public:
CMyWindow()
: m_renderTargetCriticalSection(g_renderTargetCriticalSection)
{
// ...
}
~CMyWindow()
{
// guaranteed to still be valid since our shared_ptr is keeping it alive
CSingleLock lock(m_renderTargetCriticalSection.get(), TRUE);
// ...
}
// ...
};
答案 1 :(得分:0)
问题是应用程序的主窗口在应用程序的全局对象被销毁后被销毁。这意味着当主窗口试图被销毁时g_renderTargetCriticalSection
已经是空的。
解决方案是在它的全局对象(CDBApp theApp
)调用ExitInstance()
并销毁之前销毁应用程序的主窗口。
int CDBApp::ExitInstance()
{
LOGO_RELEASE
//Destroy the Main Window before the CDBApp Object (theApp) is destroyed.
if(m_Instance.m_hWnd)
m_Instance.DestroyWindow();
return CWinApp::ExitInstance();
}
答案 2 :(得分:0)
这段代码没有意义:
int CDBApp::ExitInstance()
{
LOGO_RELEASE
//Destroy the Main Window before the CDBApp Object (theApp) is destroyed.
if(m_Instance.m_hWnd)
m_Instance.DestroyWindow();
return CWinApp::ExitInstance();
}
m_Instance是一个句柄,而不是一个类,所以它不能用来调用函数!