这是我的last question。我尝试改进我的类Thread。 构造函数接收指向函数的指针,该函数必须在新线程中运行。
class Thread {
public:
Thread(void (*p)()) {
pf=p;
}
~Thread () {}
void StartThread() {
hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadProc, NULL, 0, &threadID);
}
private:
void (*pf)();
HANDLE hThread;
unsigned threadID;
static unsigned WINAPI ThreadProc(LPVOID lpParam) {
(*pf)(); //error C2597 illegal reference to non-static member
return 0;
}
};
在ThreadProc中我需要调用TimerFunc。
void TimerFunc () {
i++;
}
此类的使用示例:
Thread *timer;
timer = new Thread(TimerFunc);
timer->StartThread();
所以它不起作用。 如果这堂课愚蠢,请有人告诉我。 将指针发送到位于类外的func可能是一个坏主意? 谢谢。
非常感谢您的建议! 现在它有效!
class Thread {
public:
Thread(void (*p)()) {
gg.pf=p;
}
~Thread ();
void StartThread() {
hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadProc, this, 0, &threadID);
}
private:
struct mm {
Thread *pThread;
void (*pf)();
} gg;
HANDLE hThread;
unsigned threadID;
static unsigned WINAPI ThreadProc(LPVOID lpParam) {
mm hh;
hh.pThread=static_cast<Thread*> (lpParam);
hh.pf=hh.pThread->gg.pf;
hh.pf();
return 0;
}
};
你怎么看?这是正确的选择吗?
答案 0 :(得分:3)
正如outhers指出的那样,问题是静态方法无法访问非静态成员。执行此类操作的常用方法是将对象作为参数传递给线程启动例程,例如:
class Thread {
public:
Thread(void (*p)()) {
pf=p;
}
~Thread () {}
void StartThread() {
// Pass this as argument to ThreadProc
hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadProc, this, 0, &threadID);
}
private:
void (*pf)();
HANDLE hThread;
unsigned threadID;
static unsigned WINAPI ThreadProc(LPVOID lpParam) {
// Get the passed Thread object
Thread *pThread = static_cast<Thread*> (lpParam);
pThread->pf();
return 0;
}
};
答案 1 :(得分:2)
问题是ThreadProc被定义为静态,这意味着它没有绑定到对象。然后,您尝试使用非静态的类成员,并且必须绑定到对象。
克服这个问题的典型方法是通过创建函数接受的void *指针将结构传递给线程。这个结构应该包含你需要的参数。在其中的某个地方,您应该有一个指向您尝试将对象绑定到的类的指针。然后,通过这个指针参考pf。
答案 2 :(得分:1)
您的ThreadProc
成员函数是静态成员函数。因此,它无权访问任何非静态成员或成员函数,包括pf
。我明白为什么你决定让TreadProc
成为静态成员函数 - 因为那样你就可以将它作为普通函数指针传递给_beginthreadex
。
嗯,如你所见,这种方法存在问题。解决这个问题并非易事。您可以查看boost thread实施情况,看看他们是如何做到的。