views:

1020

answers:

5

How do I create a thread routine of a static member function

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

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

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

This gives me the following error:

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

What am I doing wrong?

+1  A: 
class Blah
{
    static unsigned int __stdcall Start(void *);
};
Ferruccio
Why unsigned int? I'm not returning any thing from the thread. Even if I had to return something what should I return
hab
Same reason you have int main() : because your thread should return something, by design. Just return 0, if you have nothing better.
MSalters
Not workingclass Blah{ static unsigned int __stdcall Start();};unsigned int Blah::Start() {}now this error: error C2664: '_beginthreadex' : cannot convert parameter 3 from 'unsigned int (void)' to 'unsigned int (__stdcall *)(void *)'
hab
WINAPI should do the trick. When working with windows API, why not stick to their terminology? You missed the obligatory void* function argument -1
xtofl
@xtofl - thanks for the void* catch. I like to avoid using macros whenever it makes sense. In this case I could go either way.
Ferruccio
+3  A: 
class Blah
{
    static unsigned int __stdcall Start(void*); // void* should be here, because _beginthreadex requires it.
};

The routine passed to _beginthreadex must use the __stdcall calling convention and must return a thread exit code.

Implementation of Blah::Start:

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

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

Later in your code you could write any of the following:

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

In first case Function-to-pointer conversion will be applied according to C++ Standard 4.3/1. In second case you'll pass pointer to function implicitly.

Kirill V. Lyadvinsky
Nice one! Especially the function-to-pointer conversion I didn't know. +1
xtofl
+2  A: 
class Blah
{
  public:
    static DWORD WINAPI Start(void * args);
};
anon
missing the `void*` parameter that is part of the expected signature.
jalf
Thanks - the sad thing is that was copied (incorrectly) from working code - maybe I'm getting to old for this :-(
anon
when you are anyway at it with windows defines, use LPVOID for arg :)
Anders K.
+2  A: 

Following is the compiling version:

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;
}

Following are the changes required:

(1). Start() function should return unsigned int

(2). It should take a void* as the parameter.

EDIT

Deleted point (3) as per comment

Naveen
For static function `Function-to-pointer conversion` will be applied. So no need in (3).
Kirill V. Lyadvinsky
+13  A: 

Sometimes, it is useful to read the error you're getting.

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

Let's look at what it says. For parameter three, you give it a function with the signature void(void), that is, a function which takes no arguments, and returns nothing.

It fails to convert this to unsigned int (__stdcall *)(void *), which i what _beginthreadex expects:

It expects a function which:

  • Returns an unsigned int:
  • Uses the stdcall calling convention
  • Takes a void* argument.

So my suggestion would be "give it a function with the signature it's asking for".

class Blah
{
    static unsigned int __stdcall Start(void*);
};
jalf
+1 for teaching people to read!
xtofl
thanks but im not familiar with func pointers : )lemme try your solution
hab
Then this might help you some:The Function Pointer Tutorials - http://www.newty.de/fpt/index.html
TheUndeadFish