1

如何创建静态成员函数的线程例程

class Blah
{
    static void WINAPI Start();
};

// .. 
// ...
// ....

hThread = (HANDLE)_beginthreadex(NULL, 0, CBlah::Start, NULL, NULL, NULL);

这给了我以下错误:

***error C2664: '_beginthreadex' : cannot convert parameter 3 from 'void (void)' to 'unsigned int (__stdcall *)(void *)'***

我究竟做错了什么?

4

5 回答 5

16

有时,阅读您遇到的错误很有用。

cannot convert parameter 3 from 'void (void)' to 'unsigned int (__stdcall *)(void *)'

让我们看看它说了什么。对于参数三,你给它一个带有签名的函数void(void),即一个不接受任何参数并且不返回任何内容的函数。它无法将其转换为unsigned int (__stdcall *)(void *),这是_beginthreadex 预期的:

它需要一个函数:

  • 返回一个unsigned int
  • 使用stdcall调用约定
  • 进行void*辩论。

所以我的建议是“给它一个带有它要求的签名的功能”。

class Blah
{
    static unsigned int __stdcall Start(void*);
};
于 2009-08-11T12:37:10.660 回答
3
class Blah
{
    static unsigned int __stdcall Start(void*); // void* should be here, because _beginthreadex requires it.
};

传递给的例程_beginthreadex必须使用__stdcall调用约定并且必须返回一个线程退出代码

Blah::Start 的实现:

unsigned int __stdcall Blah::Start(void*)
{
  // ... some code

  return 0; // some exit code. 0 will be OK.
}

稍后在您的代码中,您可以编写以下任何内容:

hThread = (HANDLE)_beginthreadex(NULL, 0, CBlah::Start, NULL, NULL, NULL);
// or
hThread = (HANDLE)_beginthreadex(NULL, 0, &CBlah::Start, NULL, NULL, NULL);

在第一种情况下Function-to-pointer conversion,将根据 C++ 标准 4.3/1 应用。在第二种情况下,您将隐式传递指向函数的指针。

于 2009-08-11T12:09:10.237 回答
2
class Blah
{
  public:
    static DWORD WINAPI Start(void * args);
};
于 2009-08-11T12:11:31.450 回答
2

以下是编译版本:

class CBlah
{
public:
    static unsigned int WINAPI Start(void*)
    {
    return 0;
    }
};

int main()
{
    HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &CBlah::Start, NULL, NULL, NULL);

    return 0;
}

以下是所需的更改:

(1)。Start() 函数应该返回 unsigned int

(2)。它应该以 void* 作为参数。

编辑

根据评论删除点(3)

于 2009-08-11T12:17:02.107 回答
1
class Blah
{
    static unsigned int __stdcall Start(void *);
};
于 2009-08-11T11:39:57.927 回答