簡體   English   中英

VS2008 中的斷言,但 VS2005 中沒有

[英]Assertion in VS2008 but not in VS2005

從 VS2005 切換到 VS2008 SP1 后,我發現了一個我無法解釋的問題。
一個程序在 VS2005 下在發布和調試模式下都能正常工作。 在 VS2008 下,當進入調試器時,會引發一個斷言。
如果我讓程序運行(在調試或發布模式下),則根本沒有斷言。

我花了將近兩天的時間,我不明白我做錯了什么。

程序描述:我有一個基於 MFC 對話框的程序,它創建了一個用戶線程 (CWinThread),該線程創建了應用程序的主對話框。
工作線程無限循環並每秒向對話框發布一條消息。 消息在 gui 線程中處理。

我的代碼的某些部分:

gui線程的InitInstance:

BOOL CGraphicalThread::InitInstance()
{
    CGUIThreadDlg* pDlg = new CGUIThreadDlg();
    pDlg->Create(CGUIThreadDlg::IDD);
    m_pMainWnd = pDlg;
    AfxGetApp()->m_pMainWnd = pDlg;
    return TRUE;
}

工作線程:

UINT ThreadProc(LPVOID pVoid)
{
    do
    {
        AfxGetApp()->m_pMainWnd->PostMessage(WM_APP+1, (WPARAM)new CString("Hello"), NULL);
        Sleep(1000);
    }
    while(!bStopThread);

    return 0;
}

對話消息處理程序是這樣的:

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;
}

這與 VS2005 完美配合。 但是用VS2008,但是只要下斷點並進入調試模式,我就提出了一個斷言???
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.

如果我刪除 GUI 線程並將對話框創建到 CWinApp 線程中,則問題不再發生。

有人知道嗎?
難道我做錯了什么?

謝謝

// 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.

@Ismael:我已經嘗試過斷言仍然被解雇。 我發現刪除斷言的唯一方法是在 CWinApp 線程中創建對話框。 但這並不能解釋會發生什么,因為仍然有工作線程每秒發布到對話框。 總之感謝。

@daanish.rumani:我檢查了 wincore.cpp 和 CWnd::AssertValid() 完全相同(但文件的 rest 有很多差異)。

我會接受一段代碼適用於 VS2005 而不是 VS2008,但是

  1. 我看不出我做錯了什么。 如果我做錯了什么,正確的方法是什么?
  2. 為什么只有在遇到斷點並且我跳過 Sleep 調用時才會觸發斷言? 我可以很好地運行程序,即使它在調試模式下編譯,只要我不進入調試器。 這可能是調試器中的錯誤嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM