ASSERT 在 CDC SelectObject() 调用上失败 - 我可以尝试什么?
我正在开发一个多线程 win32 MFC 应用程序。我们正在渲染地图并将其显示在用户界面的窗格中,并在顶部显示自定义渲染的对象。渲染速度很慢(约 800 毫秒),这是在用户界面线程上发生的。
我试图将渲染移动到它自己的线程上,以便菜单仍然保持活泼,而其他渲染仍然可以在后台运行。 Draw 线程将使用其自己的 CDC 持续渲染。 UI 线程将调用重绘函数,该函数会锁定互斥体,并获取 CBitmap
的最后一个快照,并使用 UI 的 CDC
绘制它。使用 Draw 线程的 CD 的每个位置都被互斥体锁定。
我看到的是线程通过 CreatCompatibleBitmap
创建一个新的 CBitmap
,然后尝试将新的 CBitmap
对象选择到 Draw 线程的 <代码>CDC。
this->m_canvas.CreateCompatibleDC(&compatibleDC);
this->m_bitmap = new CBitmap();
this->m_bitmap->CreateCompatibleBitmap(&compatibleDC, m_width, m_height);
m_oldBitmap = this->m_canvas.SelectObject(m_bitmap);
此时,CGdiObject::FromHandle() 中出现调试 ASSERT 失败。
CGdiObject* PASCAL CGdiObject::FromHandle(HGDIOBJ h)
{
CHandleMap* pMap = afxMapHGDIOBJ(TRUE); //create map if not exist
ASSERT(pMap != NULL);
CGdiObject* pObject = (CGdiObject*)pMap->FromHandle(h);
ASSERT(pObject == NULL || pObject->m_hObject == h);
return pObject;
}
第二个 ASSERT 失败,因为 m_hObject 与传入的句柄不匹配。基本上,MFC 正在获取句柄,并进行查找以获取 CBitmap< /code> 对象在某种程度上与刚刚创建的 CBitmap
不匹配。
这听起来很熟悉吗?可能发生什么情况导致 FromHandle
方法返回错误的对象?我为 Draw 线程创建 CDC,然后一遍又一遍地重复使用它的方式是否存在根本缺陷?我可以采取任何方法来帮助调试/解决这个问题吗?
I'm working on a multi-threaded win32 MFC application. We are rendering a map and displaying it in a pane in the user interface along with custom-rendered objects on top. It's slow to render (~800 ms), which is happening on the User Interface thread.
I'm trying to move the rendering onto its own thread so that the menus still remain snappy while the other rendering can still run in the background. The Draw thread will render continually using its own CDC. The UI thread will call a redraw function, which locks the mutex, and takes the last snapshot of the CBitmap
and draws it using the UI's CDC
. Every location where the Draw thread's CD
C is used, is locked by the mutex.
What I'm seeing is the thread creating a new CBitmap
via CreatCompatibleBitmap
, and then trying to select the new CBitmap
object into the Draw thread's CDC
.
this->m_canvas.CreateCompatibleDC(&compatibleDC);
this->m_bitmap = new CBitmap();
this->m_bitmap->CreateCompatibleBitmap(&compatibleDC, m_width, m_height);
m_oldBitmap = this->m_canvas.SelectObject(m_bitmap);
At this point, there is a debug ASSERT failure in CGdiObject::FromHandle().
CGdiObject* PASCAL CGdiObject::FromHandle(HGDIOBJ h)
{
CHandleMap* pMap = afxMapHGDIOBJ(TRUE); //create map if not exist
ASSERT(pMap != NULL);
CGdiObject* pObject = (CGdiObject*)pMap->FromHandle(h);
ASSERT(pObject == NULL || pObject->m_hObject == h);
return pObject;
}
The second ASSERT
is failing because the m_hObject
does not match the handle passed in. Basically, MFC is taking the handle, and doing a lookup to get a CBitmap
object which somehow doesn't match the CBitmap
that was just created.
Does this sound familiar to anyone? What could be happening to cause the FromHandle
method to return the wrong object? Is there a fundamental flaw with the way I create a CDC
for the Draw thread, and then re-use it over and over? Are there any approaches I can take to help debug/fix this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
金的。句柄和对象之间的映射位于线程本地存储中。
所以基本上,存储句柄,然后从句柄创建一个 CBitmap,以便在线程之间操作它们。
我的错误在于 UI 线程创建了 CBitmap,然后从两个线程访问 CBitmap 对象。
Golden. The mapping between handles and objects are in thread-local storage.
So basically, store the handle, then create a CBitmap from the handle in order to manipulate them between threads.
My mistake was in the UI thread creating my CBitmap, and then accessing the CBitmap object from both threads.