2012-08-17 10 views
5

में शून्य * (*) (शून्य *) को शून्य * (*) (शून्य *) में परिवर्तित नहीं कर सकता है, मैं कक्षा "कैमरा प्रबंधक" के साथ एक नया धागा बनाने की कोशिश कर रहा हूं लेकिन मेरे पास निम्न त्रुटि:pthread_create फ़ंक्शन

cannot convert '*void(CameraManager:: *)(void*) to void*(*)(void*) in pthread_create function

मैं cameramanager.h फाइल में परिभाषित:

public: 
void *dequeueLoop(void *ptr); 

और cameramanager.cpp में

void CameraManager::startDequeuing(){ 
dequeuing = true; 
dequeueThreadId = pthread_create(&dequeueThread, NULL, &CameraManager::dequeueLoop, NULL); 
} 

void *CameraManager::dequeueLoop(void *ptr){ 
while(dequeuing){ 
    highSpeedCamera->dequeue(); 
    highSpeedCamera->enqueue(); 
} 

मैं declar नहीं करना चाहते ई डेक्यू एक स्थैतिक फ़ंक्शन के रूप में लॉन्च किया गया है, मैंने डेक्यू लूप को निम्न तरीके से क्लास फ्रेंड फ़ंक्शन के रूप में घोषित करने की भी कोशिश की लेकिन उसके बाद कक्षा चर के 'हाई स्पीड कैमरे' और 'डेक्यूइंग' पर दायरा नहीं है और संकलक मुझे यह भी बताता है कि 'डेक्यू लूप' इस दायरे में घोषित नहीं

एक दोस्त समारोह मैंने किया dequeueLoop बनाने के लिए:

cameramanager.h

public: 
friend void *dequeueLoop(void *ptr); 

cameramanager.cpp

void CameraManager::startDequeuing(){ 
    dequeuing = true; 
    dequeueThreadId = pthread_create(&dequeueThread, NULL, &CameraManager::dequeueLoop, NULL); 
} 
void *dequeueLoop(void *ptr){ 
    while(dequeuing){ 
     highSpeedCamera->dequeue(); 
     highSpeedCamera->enqueue(); 
    } 
} 

जहां मैं गलत कर रहा हूँ?

+1

आप इसे स्थिर सदस्य फ़ंक्शन क्यों नहीं बनाना चाहते हैं। आप हमेशा 'इस' को तर्क के रूप में पास कर सकते हैं ताकि आप अपने निजी सदस्य डेटा तक पहुंच प्राप्त कर सकें। – pstrjds

उत्तर

6

I don't want to declare dequeueLoop as a static function

यदि आप pthreads का उपयोग करना चाहते हैं, तो आपको प्रवेश बिंदु के लिए एक स्थिर या गैर-सदस्य फ़ंक्शन की आवश्यकता होगी।

static void * dequeueEntry(void * self) { 
    return static_cast<CameraManager*>(self)->dequeueLoop(); 
} 

dequeueThreadId = pthread_create(
    &dequeueThread, NULL, 
    &CameraManager::dequeueEntry, // <-- pointer to trampoline function 
    this);      // <-- pointer to object for member function 

वैकल्पिक रूप से, अगर आप एक आधुनिक संकलक है, तो आप मानक धागा पुस्तकालय के बजाय इस्तेमाल कर सकते हैं: आप इस समारोह के लिए, अपने वस्तु के लिए एक सूचक पारित गैर स्थिर सदस्य समारोह में एक ट्रैम्पोलिन के रूप में उपयोग कर सकते हैं:

std::thread thread(&CameraManager::dequeLoop, this); 
+3

यदि आपके पास आधुनिक कंपाइलर नहीं है, तो आप बूस्ट :: थ्रेड पर विचार कर सकते हैं - यह वही अच्छा वाक्यविन्यास होगा – nogard

+0

धन्यवाद, मैंने आपके द्वारा सुझाए गए पहले कार्यान्वयन की कोशिश की लेकिन जब मैं संकलित करता हूं तो मुझे निम्न त्रुटि होती है: 'फ़ंक्शन में 'शून्य * डेकएन्ट्री (शून्य *)' 'शून्य मान को अनदेखा नहीं किया जाना चाहिए क्योंकि यह' –

+0

@ गैब्रिएल गैंबोट्टो होना चाहिए: ऐसा लगता है कि आपके 'डेक्यू लूप' को कुछ भी वापस करने की घोषणा नहीं की गई है, जो आपके प्रश्न में से एक के विपरीत घोषित किया गया है वापसी 'शून्य * ', लेकिन कुछ भी वापस करने के लिए भूल जाता है। या तो थ्रेड के रिटर्न वैल्यू को वापस करने के लिए 'डेक्यू लूप' प्राप्त करें, या 'डेक्यूएन्ट्री' में एक अलग 'रिटर्न' स्टेटमेंट डालें। –

2

आप फ़ंक्शन पॉइंटर के रूप में सदस्य फ़ंक्शन के लिए पॉइंटर का उपयोग नहीं कर सकते हैं जब तक कि यह स्थैतिक न हो। आपको डेक्यू को एक फ्री फ़ंक्शन लूप करना होगा, या एक रैपर के रूप में एक फ्री फ़ंक्शन लिखना होगा।

एक मुक्त फ़ंक्शन में कक्षा के सदस्यों तक पहुंचने के लिए, आपको फ़ंक्शन को this पॉइंटर को pthread_create के अंतिम तर्क के रूप में पास करना चाहिए। फिर नि: शुल्क फ़ंक्शन ने क्लास के पॉइंटर को तर्क दिया है।

3

यदि आप चाहते हैं कि फ़ंक्शन कक्षा का सदस्य बन जाए, तो static होना चाहिए। ऐसा इसलिए है क्योंकि थ्रेड फ़ंक्शन को सीधे कॉल किया जाएगा और उसके पास वैध this पॉइंटर नहीं होगा। यह एक आवरण समारोह, कि वास्तविक वस्तु पारित हो और उसके बाद उचित सदस्य फ़ंक्शन को कॉल होने से हल किया जा सकता:

void *dequeueLoopWrapper(void *p) 
{ 
    CameraManager *cameraManager = static_cast<CameraManager*>(p); 
    camereraManager->dequeueLoop(); 
    return nullptr; 
} 

// ... 

void CameraManager::startDequeuing() 
{ 
    dequeuing = true; 
    dequeueThreadId = pthread_create(&dequeueThread, NULL, dequeueLoopWrapper, this); 
} 

लेकिन, मैं आपको नए मानक पुस्तकालय में threading support का उपयोग शुरू की सिफारिश करेंगे:

void CameraManager::startDequeuing() 
{ 
    dequeuing = true; 
    myThread = std::thread(&CameraManager::dequeueLoop, this); 
} 
संबंधित मुद्दे