【问题标题】:_beginthreadex static member function_beginthreadex 静态成员函数
【发布时间】: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 *)'***

我做错了什么?

【问题讨论】:

    标签: c++ function static multithreading member


    【解决方案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* 捕获。我喜欢在有意义的时候避免使用宏。在这种情况下,我可以选择任何一种方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-03
    • 2013-05-09
    相关资源
    最近更新 更多