c++ - MFC 调试断言失败!!wincore.cpp 第 972 行
问题描述
我在 DLL 中创建了一个 MFC 对话框,用于多个项目,它具有以下功能:使用 DLL 从主应用程序获取列表框数据。我可以通过主应用程序将字符串数据推送到 MFC 对话框,但编译后出现断言错误。此过程发生在一个线程中,其中一个线程保持对话框处于活动状态,另一个线程推送数据,如下面的代码所示。
void dbox(CDialogClass *dlg)
{
dlg->ShowDlg();
}
void input(CDialogClass *dlg)
{
string str1= "";
while (1)
{
getline(cin, str1);
//cin >> str1;
dlg->SetData(str1);
}
}
int main()
{
HMODULE hModule = ::GetModuleHandle(NULL);
if (hModule != NULL)
{
// initialize MFC and print and error on failure
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
{
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
}
else
{
CDialogClass *dlg = new CDialogClass("Title Dbox",300.0f, 300.0f, 0);
thread t1(input, dlg);
thread t2(dbox, dlg);
t1.join();
t2.join();
}
}
return 0;
}
此处 dbox() 调用位于 MFC DLL 中的 ShowDlg 函数,如下所示:
void CDialogClass::ShowDlg()
{
dlgg->title = title;
dlgg->dialogWidth = D_width;
dlgg->dialogHeight = D_height;
dlgg->pos = pos;
dlgg->Create(IDD_DIALOG1);
dlgg->ShowWindow(SW_SHOWNORMAL);
dlgg->RunModalLoop();
//dlgg->DoModal();
}
SetData() 由线程 input() 调用,它在 DLL 中有以下代码:
void CDialogClass::SetData(string data)
{
p_text = data;
dlgg->calldata(data);
}
下面是 DLL 中我的 Dialog 类的代码,仅供参考(如果需要)-
#include "stdafx.h"
#include "DlgDisp.h"
#include "afxdialogex.h"
#include "Resource.h"
#include <fstream>
#include <Thread>
IMPLEMENT_DYNAMIC(CDlgDisp, CDialogEx)
CDlgDisp::CDlgDisp(CWnd* pParent /*=NULL*/)
: CDialogEx(CDlgDisp::IDD, pParent)
{
}
CDlgDisp::~CDlgDisp()
{
}
void CDlgDisp::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_listbox);
}
BOOL CDlgDisp::OnInitDialog()
{
//Title manipulations
char *str_title;
str_title = &title[0];
SetWindowText((CAtlString)str_title);
//Size manipulations
CWnd* pctrl = GetDlgItem(IDC_LIST1);
CRect rectctrl;
SetWindowPos(NULL, 0, 0, dialogWidth, dialogHeight, SWP_NOMOVE | SWP_NOZORDER);
pctrl->GetWindowRect(rectctrl);
pctrl->SetWindowPos(NULL, 20, 20, dialogWidth-120, dialogHeight-80, SWP_NOMOVE | SWP_NOZORDER);
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
BEGIN_MESSAGE_MAP(CDlgDisp, CDialogEx)
END_MESSAGE_MAP()
void CDlgDisp::calldata(string strdata)
{
char *str_parameter;
str_parameter = &strdata[0];
CString param = _T("");
param.Format(_T("%s"), (CAtlString)str_parameter);
if (pos == 0)
{
m_listbox.InsertString(0, param);
}
else
m_listbox.AddString(param);
UpdateData(FALSE);
}
程序流程供参考:
CDlgDisp 类是从 CDialogEx 类派生的 Dialog 类。CDialogClass 用于与派生自 CDialog 类的外部应用程序进行交互。CDialogClass 有一个 CDlgDisp 类的公共成员变量。
外部应用程序 -> object.CdialogClass -> object.CDlgdisp 类
当我执行程序时它运行良好,当我尝试通过控制台输入数据时出现错误。它确实会动态地打印在列表框中,但随后会显示断言错误。
这是执行后的图像[在此处输入图像描述][1]
这是我在控制台中输入数据并按回车后的图像 [在此处输入图像描述] [2]
你们认为问题是什么?[1]:https ://i.stack.imgur.com/pXFMD.png [2]:https ://i.stack.imgur.com/eUXZ7.png
解决方案
查看发生 ASSERT 离子的源
你会发现这条评论:
// Note: if either of the above asserts fire and you are
// writing a multithreaded application, it is likely that
// you have passed a C++ object from one thread to another
// and have used that object in a way that was not intended.
// (only simple inline wrapper functions should be used)
//
// In general, CWnd objects should be passed by HWND from
// one thread to another. The receiving thread can wrap
// the HWND with a CWnd object by using CWnd::FromHandle.
//
// It is dangerous to pass C++ objects from one thread to
// another, unless the objects are designed to be used in
// such a manner.
MFC 窗口对象使用每个线程的句柄映射。这通常不允许您将对象用于其他线程的某些功能。这是可能的,但这在许多其他线程中都有讨论。
您想使用 MFC 的方式是不可能的。考虑同步。如果函数是线程安全的并且您想与其他窗口一起使用,您可以直接使用 SendMessage 和 m_hWnd 句柄。
推荐阅读
- python - 如何将球树应用于熊猫 df 列
- python-3.x - 当数组的大小不可整除时,将 numpy 数组拆分为相等的部分
- ruby-on-rails - 如何重构控制器方法?
- swift - 检查 Swift 中的连接
- c# - 如何更改用户上传文件 ASP.NET 的读/写权限
- azure - Set-AzStorageBlobContent 引发异常:路径中有非法字符
- excel - 达到特定值时需要触发计数
- python - 日期时间列上的 SQLalchemy 键错误
- android - 媒体播放器和 RecyclerView kotlin
- python - 如何多次运行python脚本?