Nach dem Wechsel von VS2005 zu VS2008 SP1 habe ich ein Problem gefunden, das ich nicht erklären kann.
Ein Programm funktioniert unter VS2005 im Freigabe- und Debug-Modus. Unter VS2008 wird beim Eingeben des Debuggers eine Assertion ausgelöst.
Wenn ich das Programm laufen lassen (im Debug-oder Release-Modus), keine Behauptung überhaupt.Behauptung in VS2008, aber nicht in VS2005
Ich verbrachte fast zwei Tage damit und ich verstehe nicht, was ich falsch mache.
Beschreibung des Programms: Ich habe einen Dialog MFC basiertes Programm, das einen Benutzer-Thread (CWinThread) erzeugt, die den Hauptdialog der Anwendung erzeugt.
Ein Worker-Thread wird endlos wiederholt und sendet jede Sekunde eine Nachricht an das Dialogfeld. Die Nachricht wird im GUI-Thread verarbeitet.
Einige Teile meines Code:
Die InitInstance des GUI-Thread:
BOOL CGraphicalThread::InitInstance()
{
CGUIThreadDlg* pDlg = new CGUIThreadDlg();
pDlg->Create(CGUIThreadDlg::IDD);
m_pMainWnd = pDlg;
AfxGetApp()->m_pMainWnd = pDlg;
return TRUE;
}
Der Arbeiter-Thread:
UINT ThreadProc(LPVOID pVoid)
{
do
{
AfxGetApp()->m_pMainWnd->PostMessage(WM_APP+1, (WPARAM)new CString("Hello"), NULL);
Sleep(1000);
}
while(!bStopThread);
return 0;
}
Der Dialog Nachrichtenhandler ist wie folgt:
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;
}
Dies funktioniert perfekt mit VS2005. Aber mit VS2008, aber sobald ein Breakpoint gesetzt und den Debugging-Modus betreten, habe ich eine Assertion ausgelöst ???
wincore.cpp Linie 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.
Wenn ich die GUI-Thread, und erstellen Sie den Dialog in den CWinApp Thread zu entfernen, tritt das Problem nicht mehr nicht.
Hat jemand eine Idee?
Mache ich etwas falsch?
Danke
Ja, ich weiß. Ich manipuliere die Fenster in einem anderen Thread nicht, sondern schreibe einfach eine Nachricht dorthin. Ich habe versucht, die rohe HWND zu verwenden, aber das Problem ist immer noch da. Wie auch immer, es erklärt nicht, warum es gut mit VS2005 und nicht mit VS2008 funktioniert. –
wincore.cpp ist für VC++ Version 8 und 9 unterschiedlich. Version 8 ist VS 2005 und Version 9 ist VS 2008 –
Ich würde empfehlen, die HWND aus dem Hauptdialog als Thread-Parameter und dann im Thread-Aufruf CWnd übergeben: : FromHandle (hWnd) -> PostMessage (...); – Ismael