Tuesday, May 02, 2006

Microsoft: You're a member - I don't want to deal with you

I tried to use a member function as a ThreadProc method in the CreateThread call, but it didn't work. The following are all of my attempts at doing it...

- "&listeners::tossToServer" and "&(listeners::tossToServer)" result in:
error C2664: 'CreateThread': cannot convert parameter 3 frpm 'DWORD (__stdcall listeners::*)(LPVOID)' to 'LPTHREAD_START_ROUTINE'.
I tried casting it to 'LPTHREAD_START_ROUTINE', but that would work either.

- "tossToServer" results in:
error C3867: 'listeners::tossToServer': function call missing argument list; use '&listeners::tossToServer' to create a pointer to member

- "&tossToServer" results in:
error C2276: '&'; illegal operation on bound member function expression

In all of the above, my statements were a little like so:
DWORD dwThreadId;
HANDLE hThread = CreateThread (NULL, 0, Thread_proc_here, Ptr_to_param, 0, &dwThreadId);

After all that testing and turning, I decided to search the WWW, or more specifically, Google. An article from Microsoft turned up on why we can't use member functions in Win32 API calls. It's available at http://support.microsoft.com/kb/q102352/ but I have an extract of the part you need to read right here:


The problem is that the function expects a C-style callback, not a pointer to a member function. A major difference is that member functions are called with a hidden argument called the "this" pointer. In addition, the format of the pointer isn't simply the address of the first machine instruction, as a C pointer is. This is particularly true for virtual functions.

If you want to use a member function as a callback, you can use a static member function. Static member functions do not receive the "this" pointer and their addresses correspond to an instruction to execute.

Static member functions can only access static data, and therefore to access nonstatic class members, the function needs an object or a pointer to an object. One solution is to pass in the "this" pointer as an argument to the member function.

--- END QUOTE ---