MFC:在工作线程中使用对象的成员函数时出现访问冲突错误
Posted
技术标签:
【中文标题】MFC:在工作线程中使用对象的成员函数时出现访问冲突错误【英文标题】:MFC: Getting Access Violation Error when Using an Object's Member Function in a Worker Thread 【发布时间】:2015-01-27 06:42:43 【问题描述】:我正在将 MFC 应用程序从 Windows XP 迁移到 Windows 7,但在完成这件事时遇到了一些重大障碍。
以这段代码为例(m_cDatabase 是 CDatabase 对象的包装类):
MyApp* pApp = (MyApp*)AfxGetApp();
pApp->m_cDatabase.CloseDatabase();
代码在主线程中运行,但如果在工作线程中运行,则会引发访问冲突异常。工作线程是使用 Windows 线程 API(带有 HANDLE 等的 API)创建的,但我看到了一些使用 MFC 线程 API(带有 Afxbeginthread 的 API 等)的代码。 Windows 线程 API 是否有可能将其丢弃?我应该尝试改用 MFC 框架吗?
【问题讨论】:
您的代码有错误。无论您使用哪种 API,它们都会在那里。 是的,我刚刚尝试使用 MFC API。还是没有骰子。看来我得想办法破解这件事了。 如果您需要从另一个线程访问 MFC 对象,您必须使用AfxBeginThread
来生成工作线程,否则 MFC 的多线程支持将无法正确初始化。 See here for a similar question.
【参考方案1】:
作为一般规则,从 MFC 类派生的对象(我们称这些 MFC 对象)只能从创建它们的线程访问;这是因为许多 MFC 对象是底层对象的瘦包装器(例如,大多数 CWnd
派生的东西)并且内部数据存储在特定于线程的映射中。
在不知道m_cDatabase
代表什么的情况下,很难知道它是否属于上述对象类别,但鉴于您正在崩溃,我会说它是。
您有几个选择。可能最简单的两个是:
-
您可以在线程本身中创建
m_cDatabase
并使用它。您将需要传递构造它所需的所有参数。您还需要对线程使用的任何其他 MFC 对象实例执行相同的操作。
您可以查看m_cDatabase
是其实例的类是否提供了一种检索线程安全的底层句柄的方法。如果是这样,您可以将句柄传递给线程,然后线程可以直接访问句柄,或者如果该类提供类似FromHandle
的方法,则可能围绕它构造一个 MFC 包装器。
【讨论】:
感谢您的帮助,尼克!不幸的是,该类没有办法传递线程安全句柄,所以我可能会使用 #1 之类的东西。以上是关于MFC:在工作线程中使用对象的成员函数时出现访问冲突错误的主要内容,如果未能解决你的问题,请参考以下文章