将CreateThread与lambda一起使用

sir*_*lot 7 c++ winapi

只是试验,但我想知道是否可以使这个代码工作(如在编译中):

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();
}
Run Code Online (Sandbox Code Playgroud)

我有这种唠叨的怀疑,因为LPTHREAD_START_ROUTINE回调的标准签名是DWORD WINAPI Callback(PVOID)我无法在没有添加(但语​​法上非法)WINAPI标签的情况下编译它.说到哪些,究竟是什么WINAPICALLBACK(比如说WndProc)属性?我从来没有真正理解为什么在某些情况下你可以在函数上有多个属性.

Jon*_*ter 15

实际上,使用Visual C++ 2012及更高版本可以实现这一点; 引用微软的C++功能支持列表:

此外,在Visual Studio 2012中的Visual C++中,无状态lambda可以转换为函数指针....我们已经将无状态lambda转换为具有任意调用约定的函数指针.当您使用期望像__stdcall函数指针之类的API时,这很重要

因此,在Visual C++ 2012中,您可以执行以下操作:

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

这意味着您还可以将lambdas与其他期望回调函数的API函数一起使用(例如,EnumWindows()等等CreateDialogParam()).

  • 啊哈!我很想知道这是如何工作的,因为x86 ABI需要`__stdcall`用于(大多数)线程入口点(x64并不重要).谢谢你指出这一点,**+ 1** (3认同)