_beginthreadex 静态成员函数

Posted

技术标签:

【中文标题】_beginthreadex 静态成员函数【英文标题】:_beginthreadex static member function 【发布时间】:2009-08-11 11:34:32 【问题描述】:

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

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 *)'***

我做错了什么?

【问题讨论】:

【参考方案1】:

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

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*);
;

【讨论】:

谢谢,但我不熟悉 func 指针 :) 让我试试你的解决方案 那么这可能会对您有所帮助:函数指针教程 - newty.de/fpt/index.html【参考方案2】:
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 应用。在第二种情况下,您将隐式传递指向函数的指针。

【讨论】:

不错的一个!尤其是我不知道的函数到指针的转换。 +1【参考方案3】:
class Blah

  public:
    static DWORD WINAPI Start(void * args);
;

【讨论】:

缺少作为预期签名一部分的 void* 参数。 谢谢 - 可悲的是从工作代码中(错误地)复制了 - 也许我已经老了:-( 当您使用 Windows 定义时,请使用 LPVOID 作为 arg :)【参考方案4】:

以下是编译版本:

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)点

【讨论】:

将应用静态函数Function-to-pointer conversion。所以(3)中不需要。【参考方案5】:
class Blah

    static unsigned int __stdcall Start(void *);
;

【讨论】:

为什么是无符号整数?我没有从线程返回任何东西。即使我必须退回一些东西我应该退回什么 同样的原因你有 int main() :因为你的线程应该返回一些东西,设计。如果没有更好的,就返回 0。 不是工作类 Blah static unsigned int __stdcall Start(); ; unsigned int Blah::Start() 现在出现此错误:错误 C2664:'_beginthreadex':无法将参数 3 从 'unsigned int (void)' 转换为 'unsigned int (__stdcall *)(void *)' WINAPI 应该可以解决问题。使用 Windows API 时,为什么不坚持他们的术语呢?您错过了强制性的 void* 函数参数 -1 @xtofl - 感谢 void* 捕获。我喜欢在有意义的时候避免使用宏。在这种情况下,我可以选择任何一种方式。

以上是关于_beginthreadex 静态成员函数的主要内容,如果未能解决你的问题,请参考以下文章

DLL导出类静态成员函数问题

C++ 非静态成员函数的非法调用

C++_类中静态成员

C++_类中静态成员

C++_类中静态成员

C++_类中静态成员