DXUT库,CDXUTDialogResourceManager的一个不太好发现的问题
来源:互联网 发布:融资出让股份算法 编辑:程序博客网 时间:2024/04/30 02:01
如果按照DXUT例子的编码方式,很难出现这个问题的,但是这两日闲来无事,将DXUT分到了一个DLL内,结果……
退出时报错!
不断注释代码,最后发现是CDXUTDialogResourceManager惹的祸。再一检查,有些心得,遂拿来共享。
原因是这样的:
CDXUTDialogResourceManager在析构函数里干掉Cache(Delete):
//--------------------------------------------------------------------------------------
CDXUTDialogResourceManager::~CDXUTDialogResourceManager()
{
int i;
for( i=0; i < m_FontCache.GetSize(); i++ )
{
DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
SAFE_DELETE( pFontNode );
}
m_FontCache.RemoveAll();
for( i=0; i < m_TextureCache.GetSize(); i++ )
{
DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i );
SAFE_DELETE( pTextureNode );
}
m_TextureCache.RemoveAll();
CUniBuffer::Uninitialize();
CDXUTIMEEditBox::Uninitialize();
}
//--------------------------------------------------------------------------------------
而在OnDestroyDevice里真正Release这些资源:
//--------------------------------------------------------------------------------------
void CDXUTDialogResourceManager::OnDestroyDevice()
{
int i=0;
m_pd3dDevice = NULL;
// Release the resources but don't clear the cache, as these will need to be
// recreated if the device is recreated
for( i=0; i < m_FontCache.GetSize(); i++ )
{
DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
SAFE_RELEASE( pFontNode->pFont );
}
for( i=0; i < m_TextureCache.GetSize(); i++ )
{
DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i );
SAFE_RELEASE( pTextureNode->pTexture );
}
SAFE_RELEASE( m_pSprite );
}
//--------------------------------------------------------------------------------------
一般说来,在例子中,这个RM都是以全局变量形式存在的:
extern CDXUTDialogResourceManager g_DialogResourceManager; // manager for shared resources of dialogs
这就有一个问题,OnDestroyDevice和析构函数究竟哪个在先?这就要看OnDestroyDevice的最终调用者DXUTState这个全局变量和g_DialogResourceManager这个全局变量的析构先后顺序了。
一般,如果这些代码和您的代码都编译到一个EXE,则顺序大凡是先State析构,调用DestroyDevice再RM析构,这就对了,既Release又Delete。
而在将DXUT封到Dll后,便发生了位于Dll的State后于位于EXE 的 RM析构的情况,这导致了先调用了RM的析构函数,然后才调用了State析构和OnDestroyDevice!!!
这意味着先调用了Delete,然后在Release的时候就找不着北了,资源没有Release,DXUT自然会报错!
由此得出一个结论:VC的CRT在退出时,先干掉了EXE本身的全局变量,然后才去释放各个DLL……
写到这里后,又发现DXUTState是一个非导出类,遂导出之,结果依旧……
不知对否,遂又作测试,发现凡是EXE中的全局变量,全都在Dll的State前析构。
extern CDXUTDialog g_HUD; // dialog for standard controls
extern CDXUTDialog g_SampleUI; // dialog for sample specific controls
皆如此。
解决的方案就近乎简单了,DialogRM 既然都析构了,何不调用自己的Release?为何一定要在State析构时才调用呢?
因此为增加一句:
CDXUTDialogResourceManager::~CDXUTDialogResourceManager()
{
[color=blue] /////////////////////////////////////////////////
OnDestroyDevice();
/////////////////////////////////////////////////
[/color]
int i;
for( i=0; i < m_FontCache.GetSize(); i++ )
{
DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
SAFE_DELETE( pFontNode );
}
m_FontCache.RemoveAll();
for( i=0; i < m_TextureCache.GetSize(); i++ )
{
DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i );
SAFE_DELETE( pTextureNode );
}
m_TextureCache.RemoveAll();
CUniBuffer::Uninitialize();
CDXUTIMEEditBox::Uninitialize();
}
去掉其他地方对RM 的OnDestroyDevice 的调用。
再编译连接,成功,不会再在退出时报错了。
结论:
该谁的事情谁自己处理,别让别人擦屁股,否则总会受人牵制。
欢迎大家指正 ^_^
- DXUT库,CDXUTDialogResourceManager的一个不太好发现的问题
- 一个有点不太好理解的有关继承问题
- 发现一个FireFox的问题
- 发现android的一个问题
- 发现一个有趣的问题。
- 不太好用的windows
- DXUT为基础的控件库
- 发现一个很牛B的问题
- 发现一个gdm的奇怪问题
- DELPHI6开发数据库发现的一个问题
- 今天发现CString的一个问题
- 这是今天发现的一个问题!
- 今天发现一个很奇怪的问题
- JSF应用时候发现的一个问题。
- 发现IE中文本框的一个问题
- 今天发现一个很暴汗的问题!
- 对象初始化时发现的一个问题
- 使用dom4j时发现的一个问题
- Java传参方式小结
- 一个锅炉方面论坛和一个网站
- 我,在这里
- Mobile Robot
- 方便的boost_python
- DXUT库,CDXUTDialogResourceManager的一个不太好发现的问题
- SQL Server 2000 BUGs List
- 有感于《水和蒸汽性质计算软件包》
- [转载]建立2004个超级帐号的代码
- 移动机器人
- [转载]Windows 2000系统中如何获取系统的启动时间
- web历史记录
- [转载]Windows 2000中获取CPU使用率
- [转载]多线程DDOS攻击源代码