访问线程(MFC)中的主对话框变量

时间:2015-06-25 08:05:54

标签: c++ multithreading visual-c++ mfc

我有一个使用MFC的GUI应用程序。我正在使用AfxBeginThread()来处理一些数据。我在访问线程中的主对话框时遇到问题:

通过这个结构,我将主对话框处理程序和指向main dlg对象的指针传递给线程。但是在strcpy()行调试器停止并显示 pDlg-> 0x430f0020 {CTabDlg hWnd = ???}

typedef struct {
    LPVOID myHandle;
    LPVOID myPointer;
} sParamData;


UINT WorkerThreadProc_type2( LPVOID Param )
{


    UpdInfo info;   
    sParamData *s;

    s = (sParamData*)Param;
    HWND hMainHandle = (HWND) (*s).myHandle;
    CtabDlg* pDlg = (CtabDlg*)(*s).myPointer;

    strcpy(apikey, pDlg->m_sVar);
...
}

我尝试了XP和Windows 7操作系统。在XP中它总是崩溃,但在Seven中它起作用。这就是我将结构传递给线程的方式:

sParamData s;
    s.myHandle = (HWND)GetSafeHwnd();
    s.myPointer = (CtabDlg*) this;

    if(CurrTab == 1)
    {
        AfxBeginThread(WorkerThreadProc_type2, &s, THREAD_PRIORITY_NORMAL,0,0,NULL);
        pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);

感谢您的时间!

1 个答案:

答案 0 :(得分:3)

如果您的代码与您的实际情况完全相同,那么您在这里声明一个本地sParamData并将其地址传递给线程。这给出了竞争条件:在线程开始执行之前,s可能超出范围(或者到达其内容被复制的点)。

sParamData s;
s.myHandle = (HWND)GetSafeHwnd();
s.myPointer = (CtabDlg*) this;

if(CurrTab == 1)
{
    AfxBeginThread(WorkerThreadProc_type2, &s, THREAD_PRIORITY_NORMAL,0,0,NULL);
    pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);

最简单的解决方法可能是在堆上分配s并在复制内容后在线程中删除它。

像这样:

sParamData *s = new sParamData ;
s->myHandle = (HWND)GetSafeHwnd();
s->myPointer = (CtabDlg*) this;

if(CurrTab == 1)
{
    AfxBeginThread(WorkerThreadProc_type2, s, THREAD_PRIORITY_NORMAL,0,0,NULL);
    pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);

然后,在线程内

UINT WorkerThreadProc_type2( LPVOID Param )
{
    UpdInfo info;   
    sParamData *s = (sParamData*)Param;
    HWND hMainHandle = (HWND) s->myHandle;
    CtabDlg* pDlg = (CtabDlg*)s->.myPointer;
    // assuming s will no longer be used you can delete it here
    delete s ;