3

关于 C++ 中的函数指针,类函数和全局函数有什么区别?我在问,因为如果函数是类成员,Windows CreateThread 方法似乎不接受线程代码进入的函数。

当它是全局方法时,我可以将函数(线程代码进入)传递给 CreateThread 消息,但是一旦我将其设为类的成员,我就会收到错误“[方法布局]类型的参数与参数不兼容LPTHREAD_START_ROUTINE 类型的“。ClassName::* 现在在中间;这会影响它吗?

解决方法是什么?

4

2 回答 2

5

成员函数指针 ( ) 与函数指针 ( DWORD(WINAPI Foo::*)(LPVOID)) 的类型不同DWORD(WINAPI *)(LPVOID)。成员函数有一个隐藏this参数,导致签名不匹配。

最简单的方法是使用 C++11 的<thread>头文件:

struct Foo {
    void threadProc() {}
};

int main() {
    Foo foo;
    std::thread t{&Foo::threadProc, foo, /*other arguments to threadProc*/};
    t.join();
}

如果必须求助于CreateThread,请使用void *参数来传递实例:

struct Foo {
    DWORD threadProc() {...}
};

extern "C" DWORD WINAPI proxyThreadProc(LPVOID userData) {
    auto foo = static_cast<Foo *>(userData);
    if (foo) {foo->threadProc();}
}

int main() {
    Foo foo;
    CreateThread(..., proxyThreadProc, &foo, ...);
}

你类中的那个现在几乎可以是你想要的任何东西(比如 a std::function)并且仍然可以工作,只要它在代理过程中使用正确的参数调用。

于 2013-08-14T11:05:03.067 回答
0

是的,正如@chris 所说,有一个隐藏的指针,它将在参数末尾连接。线程执行该操作时,不知道匹配到最后一个参数位置的指针,完成后无法恢复该函数的堆,因此禁止使用类的非静态成员函数驱动一个线程函数,除了类的全局函数或静态成员函数。

于 2013-08-14T12:32:35.183 回答