我有这个代码:
// ------- My dialog header file ----------
class CMexifierDlg : public CDialogEx {
public:
unsigned int static CMexifierDlg::doit(LPVOID pParam); // this is the thread
CMexifierDlg* pMexifierDlg=this;
int x, // used to initialize the dialog AND by thread
y, // set by dialog, used to pass info to thread
z // used by MULTIPLE thread functions, but NOT by dialog
};
// ------- My CPP file -----
void CMexifierDlg::OnClickedCheck1() {
CMexifierDlg* myparm; myparm = pMexifierDlg;
AfxBeginThread(doit, (LPVOID)myparm);
// thread terminates itself when job is done
}
// ----- my thread function
unsigned int CMexifierDlg::doit(LPVOID pParam) {
// this is where the actual work happens
CMexifierDlg* D_ptr=(CMexifierDlg*)pParam;
int y = x; // doesn’t compile
int y = D_ptr->x; // fails at runtime
// now we make many calls (as part of thread)
// to other functions that need D_ptr
return 0; // thread completed successfully
}
头文件有很多变量,其中一些仅由我的主(也是唯一)对话框需要,其中一些由对话框和我在按下按钮时从对话框创建的一个线程共享,一些被使用仅由线程内调用的许多函数。线程启动后,它会在对话框中允许任何其他操作之前运行到完成,但退出整个程序除外。但是,一旦线程完成,就可以使用对话框中的新数据重新启动它。 有人可以告诉我我做错了什么吗?我迷失了理解如何将正确的东西传递给我的线程。我尝试的一件事是将我的仅线程 var 定义作为全局数据移动到 .CPP 文件并且 SEEMS 没问题(但这是正确的做法)?
你显然做不到
int y= x; // doesn’t compile
因为你的线程函数是
static
并且没有类实例成员变量。
你的
int y= D_ptr->x; // fails at runtime
看起来不错。我在我的测试项目中创建了一个类似的代码,它工作正常。
您的问题(“运行时失败”)必须在其他地方。
提前一点代码审查:
不要在类声明中初始化
pMexifierDlg
。更好的地方是在构造函数中进行:
CMexifierDlg* m_pMexifierDlg; // also prefix members with m_ or something to make clear in the code that it's a class member
void CMexifierDlg::CMexifierDlg()
{
m_pMexifierDlg = this;
}
但我会完全省略
m_pMexifierDlg
步骤,因为无论如何this
在成员函数代码中无所不在。就这样吧:
AfxBeginThread(doit, (LPVOID)this);
所以你也可以删除不必要的
myparm
赋值。
话虽如此,我认为让工作线程作为类之外的单独实体运行是可取的。例如,如果您关闭或销毁对话框,工作人员将不会退出。将 gui 代码与您的逻辑代码分开总是一个好主意,即使您有一个对话框并且一次只有一个线程以某种方式与之关联,如果您直接从工作线程执行 gui 操作,您可能会遇到陷阱。操纵像
int
s 这样的原子变量可能有效,但使用 CMutex
来处理更复杂的事情,例如 CString
.
如果你想在一个类中有工作线程,除了
CMexifierDlg
之外创建一个单独的类。
我建议您仔细研究实例化 C++ 类、
this
指针的生命周期等