2013-08-21 9 views
5

बस प्रयोग के साथ CreateThread का प्रयोग करें, लेकिन मैं सोच रहा था अगर यह (संकलन के रूप में) इस कोड को काम करने के लिए संभव है:एक लैम्ब्डा

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 टैग के बिना संकलित करने में सक्षम नहीं होगा। जिसमें से बात कर रहे हैं, WINAPI और CALLBACK (WndProc कहने के लिए) वास्तव में क्या हैं? मैंने कभी नहीं समझा है कि क्यों कुछ परिस्थितियों में आप एक समारोह पर कई विशेषताओं को प्राप्त कर सकते हैं।

+0

'मुख्य' को वापसी प्रकार के रूप में 'int' होना आवश्यक है। आपको '__stdcall' lambda की भी आवश्यकता होगी, जो संभव नहीं है। आप इसे लैम्ब्डा (या कुछ भी) लेने के लिए लपेट सकते हैं, या फिर '' का उपयोग करें। – chris

+7

चूंकि आप स्पष्ट रूप से सी ++ 11 का उपयोग कर रहे हैं, क्यों न केवल 'std :: thread' का उपयोग करें जो पोर्टेबल है और प्लेटफार्म-विशिष्ट' CreateThread' की बजाय लैम्बडास के साथ अच्छी तरह से एकीकृत करता है? – syam

+0

मैंने केवल सीखना शुरू कर दिया। लेकिन मैं उसमें देख लूंगा। धन्यवाद! – sircodesalot

उत्तर

11

असल में दृश्य सी ++ 2012 और उससे ऊपर के साथ यह संभव है; Microsoft's list of C++ feature support से उद्धृत करने के लिए:

इसके अतिरिक्त विजुअल C++ विजुअल स्टूडियो 2012 में में, राज्यविहीन lambdas संकेत दिए गए कार्य करने के लिए परिवर्तनीय हैं। ... हमने स्टेटलेस लैम्बडास फ़ंक्शन पॉइंटर्स में परिवर्तनीय बना दिया है जो मनमाने ढंग से सम्मेलनों को कॉल कर रहा है। यह महत्वपूर्ण है जब आप ऐसे API __stdcall समारोह संकेत की तरह बातें उम्मीद का उपयोग कर रहे

तो दृश्य 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)); 

इसका मतलब है आप भी अन्य एपीआई के साथ lambdas उपयोग कर सकते हैं फ़ंक्शन जो कॉलबैक फ़ंक्शंस की अपेक्षा करते हैं (उदाहरण के लिए EnumWindows() और CreateDialogParam() जैसी चीजें)। ;

+2

आह हा! मुझे आश्चर्य हुआ कि यह कैसे काम करेगा x86 एबीआई को इसके थ्रेड एंट्री-पॉइंट्स (x64 वास्तव में कोई फर्क नहीं पड़ता) के लिए '__stdcall' की आवश्यकता है। इसे इंगित करने के लिए धन्यवाद, ** + 1 ** –

2

आप चीजों को थोड़ा कम शब्दों वाले का उपयोग कर स्वत: :)

auto dontThreadOnMe = [](LPVOID data) -> DWORD { 
    int value = *(int*)data; 
    std::cout << value << std::endl; 
    std::cout << "This callback executed successsfully" << std::endl; 
    return 0; //don't forget your return code! 
}; 

int number = 42; 
auto thread = CreateThread(nullptr, 0, dontThreadOnMe, &number, 0, nullptr); 

कॉपी पेस्ट नशेड़ी जो बाद में इस जवाब खोजने के लिए, कर सकते हैं या), यह आप सभी की जरूरत है:

auto work = [](LPVOID data) -> DWORD { return 0; }; 
int thread_param = 42; 
auto thread = CreateThread(nullptr, 0, work, &thread_param, 0, nullptr); 
+0

कंपाइलर का कहना है कि मैं एक लैम्ब्डा को LPTHREAD_START_ROUTINE में नहीं डाल सकता – J3STER

0

कम से कम वर्तमान * Mingw64 के संस्करणों में आप []() WINAPI {} के रूप में, एक लैम्ब्डा समारोह के बुला सम्मेलन निर्दिष्ट कर सकते हैं:

CreateThread(
    nullptr, // lpThreadAttributes 
    0,  // dwStackSize 
    [](void *param) WINAPI -> DWORD { // lpStartAddress 
     (void) param; 
     return 0; 
    }, 
    nullptr, // lpParameter 
    0,  // dwCreationFlags 
    nullptr // lpThreadId 
); 

*) i686-w64-mingw32-g ++ - win32 (जीसीसी) 6.3.0 20170516 के साथ परीक्षण किया गया। पहले संस्करण भी काम कर सकता है।

संबंधित मुद्दे