Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function pointer as a member of a class

What's the difference between a class function and global function with regard to function pointers in C++? I'm asking as the Windows CreateThread method doesn't seem to accept the function that the thread code goes in if the function is a class member.

I can pass the function (that the thread code goes in) to the CreateThread message when it is a global method, but once I make it a member of a class I get the error "argument of type [method layout] is incompatible with parameter of type LPTHREAD_START_ROUTINE". ClassName::* is in the middle now; is this affecting it?

What is the way around this?

like image 728
Ghost Avatar asked Apr 18 '26 14:04

Ghost


1 Answers

Member function pointers (DWORD(WINAPI Foo::*)(LPVOID)) are different types than function pointers (DWORD(WINAPI *)(LPVOID)). Member functions have a hidden this parameter, causing a signature mismatch.

The easiest way to do this is to use C++11's <thread> header:

struct Foo {
    void threadProc() {}
};

int main() {
    Foo foo;
    std::thread t{&Foo::threadProc, foo, /*other arguments to threadProc*/};
    t.join();
}

If you have to resort to CreateThread, make use of the void * parameter to pass the instance:

struct Foo {
    DWORD threadProc() {...}
};

extern "C" DWORD WINAPI proxyThreadProc(LPVOID userData) {
    auto foo = static_cast<Foo *>(userData);
    if (foo) {foo->threadProc();}
}

int main() {
    Foo foo;
    CreateThread(..., proxyThreadProc, &foo, ...);
}

The one in your class can now be pretty much whatever you want (like a std::function) and still work, as long as it's called with the right arguments from within the proxy procedure.

like image 170
chris Avatar answered Apr 20 '26 03:04

chris