none
一个困扰很久的问题 RRS feed

  • 问题

  • 在线程中我想自由的调用非静态成员函数和非静态数据成员
    我面向对象的思想,开了一线程,在头文件中定义如下:
    static DWORD WINAPI ThreadProc1(LPVOID lpParameter);
    CPP文件:
    DWORD WINAPI CtestDlg::ThreadProc1(LPVOID lpParameter)
    {
     CtestDlg* dlg = (CtestDlg*)lpParameter;//可能是这里有问题
     dlg->print();/*----print()是非静态函数,----*/
     return 0;
    }

    void CtestDlg::print(void)
    {
     CDC *pdc;
     pdc = GetDC();
     pdc->TextOutW(10, 10, _T("hello"));
    }

    在BTN函数中执行线程,程序在调试中没有报错,在执行中报错:
    Unhandled exception at 0x5712e11c (mfc100ud.dll) in test.exe: 0xC0000005: Access violation reading location 0x00000020.
    光标提示:
    _AFXWIN_INLINE CDC* CWnd::GetDC()
    { ASSERT(::IsWindow(m_hWnd)); return CDC::FromHandle(::GetDC(m_hWnd)); }

    我想知道要怎样改?


    xiao
    2010年12月24日 23:03

答案

  • 不能在非mfc创建的ui线程中使用FromHandle。

    FromHandle会将创建的对象放在一个和线程绑定的列表中,然后在空余的时候删除这个对象。

    而你创建的线程没有这个列表,所有出错了。而且也没有删除对象的时机,因为没有mfc写的消息循环。

    解决方式就是:

    HDC hdc = GetDC(m_hWnd);

    TextOutW(....)//参数背不出

    ReleaseDC(hdc);//要releasedc,你上面的也要

    虽然这是线程安全的,但还是不建议这样做。

    • 已标记为答案 wh_xiao 2010年12月27日 1:39
    2010年12月26日 5:55

全部回复

  • 首先,不建议跨线程使用MFC的界面对象,因为他们不是线程安全的

    然后关于你的问题因该是参数传错了

    2010年12月25日 3:00
  • 非静态函数:

    void CtestDlg::print(void)
    {
     AfxMessageBox(_T("hello!\r\nthread1 is working!\r\nthread1 calling non-static function successed!"));
     CDC *pdc = GetDC();
     pdc->TextOutW(10, 10, _T("hello"));
    }

    在按钮响应函数中调用没有报错,但是在线程中调用就报错:

    _AFXWIN_INLINE CDC* CWnd::GetDC()
     { ASSERT(::IsWindow(m_hWnd)); return CDC::FromHandle(::GetDC(m_hWnd)); }

    断言宏这里报错,这是为什么?


    xiao
    2010年12月25日 12:02
  • 不能在非mfc创建的ui线程中使用FromHandle。

    FromHandle会将创建的对象放在一个和线程绑定的列表中,然后在空余的时候删除这个对象。

    而你创建的线程没有这个列表,所有出错了。而且也没有删除对象的时机,因为没有mfc写的消息循环。

    解决方式就是:

    HDC hdc = GetDC(m_hWnd);

    TextOutW(....)//参数背不出

    ReleaseDC(hdc);//要releasedc,你上面的也要

    虽然这是线程安全的,但还是不建议这样做。

    • 已标记为答案 wh_xiao 2010年12月27日 1:39
    2010年12月26日 5:55