sircodesalot sircodesalot - 11 months ago 182
C++ Question

Use CreateThread with a lambda

Just experimenting, but I was wondering if it's possible to make this code work (as in compile):

void main() {
int number = 5;

DWORD(*dontThreadOnMe)(PVOID) = [](PVOID data) {
int value = *(int*) data;

cout << value << endl;
cout << "This callback executed successsfully" << endl;
};

CreateThread(NULL, NULL, dontThreadOnMe, &number, NULL, NULL);
cin.get();
}


I have this nagging suspicion that because the standard signature for a
LPTHREAD_START_ROUTINE
callback is
DWORD WINAPI Callback(PVOID)
I won't be able to get this to compile without the added (but grammatically illegal)
WINAPI
tag. Speaking of which, what exactly are the
WINAPI
and
CALLBACK
(for say
WndProc
) attributes? I've never really understood why in certain circumstances you could have multiple attributes on a function.

Answer Source

Actually this is possible with Visual C++ 2012 and above; to quote from Microsoft's list of C++ feature support:

Additionally in Visual C++ in Visual Studio 2012, stateless lambdas are convertible to function pointers. ... we've made stateless lambdas convertible to function pointers that have arbitrary calling conventions. This is important when you are using APIs that expect things like __stdcall function pointers

So in Visual C++ 2012 you can do something like:

unsigned int id;
HANDLE hThread = reinterpret_cast<HANDLE>(_beginthreadex(0, 0,
    [](void* pData) -> unsigned int {
        // I'm a thread!
        return 0;
    }, pThreadData, 0, &id));

This means you can also use lambdas with other API functions that expect callback functions (things like EnumWindows() and CreateDialogParam(), for example).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download