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:在工作线程中使用对象的成员函数时出现访问冲突错误的主要内容,如果未能解决你的问题,请参考以下文章

MFC中多线程中静态函数调用成员函数的问题

在 MFC 中同时显示消息和进度时出现问题?

转:MFC中创建多线程

使用MFC中的AfxBeginThread创建多线程

在 VS2015 中访问类成员时出现运行时错误,但在 Linux 上没有

MFC C++ 使用静态成员和编译问题