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

Access to main dialog variables within thread (MFC)

本文关键字:对话框 变量 线程 MFC 访问      更新时间:2023-10-16

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

通过这个结构,我将主对话框处理程序和指向主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和Windows7操作系统。在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);

感谢您抽出时间!

如果您的代码与实际情况完全一样,那么在这里您声明了一个本地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 ;