7

実験中ですが、このコードを(コンパイルのように)機能させることができるかどうか疑問に思っていました:

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

LPTHREAD_START_ROUTINEコールバックの標準的な署名は であるため、追加された (ただし文法的には違法な)タグDWORD WINAPI Callback(PVOID)なしではこれをコンパイルすることができないのではないかと、私はしつこく疑っています。WINAPIそういえば、WINAPIand CALLBACK(たとえばWndProc) 属性とは正確には何ですか? 特定の状況で関数に複数の属性を持たせることができる理由を本当に理解したことがありません。

4

3 に答える 3

15

実際、これは Visual C++ 2012 以降で可能です。Microsoft の C++ 機能サポートのリストから引用するには:

さらに、Visual Studio 2012 の Visual C++ では、ステートレス ラムダを関数ポインターに変換できます。...ステートレスラムダを、任意の呼び出し規約を持つ関数ポインターに変換できるようにしました。これは、__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));

これは、コールバック関数を期待する他の A​​PI 関数 (EnumWindows()CreateDialogParam()など) でラムダを使用することもできることを意味します。

于 2013-08-21T21:22:56.817 に答える