Après avoir basculé de VS2005 à VS2008 SP1, j'ai trouvé un problème que je ne peux pas expliquer.
Un programme fonctionne correctement sous VS2005 en mode release et debug. Sous VS2008, lorsque vous entrez dans le débogueur, un assert est levé.
Si je laisse le programme s'exécuter (en mode debug ou release), pas d'assertion du tout.Assertion dans VS2008 mais pas dans VS2005
J'ai passé presque deux jours sur ceci et je ne comprends pas ce que je fais mal.
Description du programme: J'ai un programme de dialogue MFC qui crée une qui crée la boîte de dialogue principale de l'application thread utilisateur (CWinThread).
Un thread de travail boucle indéfiniment et publie chaque seconde un message dans le dialogue. Le message est traité dans le thread graphique.
Certaines parties de mon code:
Le InitInstance du fil de IUG:
BOOL CGraphicalThread::InitInstance()
{
CGUIThreadDlg* pDlg = new CGUIThreadDlg();
pDlg->Create(CGUIThreadDlg::IDD);
m_pMainWnd = pDlg;
AfxGetApp()->m_pMainWnd = pDlg;
return TRUE;
}
Le thread de travail:
UINT ThreadProc(LPVOID pVoid)
{
do
{
AfxGetApp()->m_pMainWnd->PostMessage(WM_APP+1, (WPARAM)new CString("Hello"), NULL);
Sleep(1000);
}
while(!bStopThread);
return 0;
}
Le gestionnaire de messages dialogue est comme ceci:
LRESULT CGUIThreadDlg::OnMsg(WPARAM wp, LPARAM lp)
{
CListBox* pList = (CListBox*)GetDlgItem(IDC_LIST1);
CString* ps = (CString*)wp;
pList->InsertString(-1, *ps);
delete ps;
return 1L;
}
Cela fonctionne parfaitement bien avec VS2005. Mais avec VS2008, mais dès qu'un a mis un point d'arrêt et entrer dans le mode de débogage, j'ai une assertion soulevée ???
ligne wincore.cpp 906
CObject* p=NULL;
if(pMap)
{
ASSERT((p = pMap->LookupPermanent(m_hWnd)) != NULL ||
(p = pMap->LookupTemporary(m_hWnd)) != NULL);
}
ASSERT((CWnd*)p == this); // must be us
// 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.
Si je retire le fil de l'interface graphique et de créer la boîte de dialogue dans le fil CWinApp, le problème ne se produit plus.
Est-ce que quelqu'un a une idée?
Est-ce que je fais quelque chose de mal?
Merci
Oui, je sais. Je ne manipule pas les fenêtres dans un autre fil, je ne fais que poster un message dessus. J'ai essayé d'utiliser le HWND brut mais le problème est toujours là. Quoi qu'il en soit, cela n'explique pas pourquoi cela fonctionne bien avec VS2005 et pas avec VS2008. –
wincore.cpp est différent pour VC++ versions 8 et 9. La version 8 est VS 2005 et la version 9 est VS 2008 –
Je recommanderais de passer le HWND de la boîte de dialogue principale comme paramètre de thread, puis dans l'appel de thread CWnd: : FromHandle (hWnd) -> PostMessage (...); – Ismael