मैं एक कैमरा एपीआई का उपयोग कर रहा हूं जो कि हर बार एक नई छवि होने पर कॉलबैक फ़ंक्शन को कॉल करता है। कॉलबैक फ़ंक्शन को निम्न के रूप में पास किया जाता है:

BOOL WINAPI StTrg_SetTransferEndCallback(HANDLE hCamera, funcTransferEndCallback func, PVOID pvContext);

जहाँ funcTransferEndCallback है:

typedef void (WINAPI *funcTransferEndCallback)(HANDLE hCamera, DWORD dwFrameNo, DWORD dwWidth, DWORD dwHeight, WORD wColorArray, PBYTE pbyteRaw, PVOID pvContext);

मैं कॉलबैक फ़ंक्शन नहीं करना चाहता, लेकिन वास्तव में इसके बजाय कक्षा में एक विधि का उपयोग करता हूं। मैं इस StTrg_SetTransferEndCallback() को अपने क्लैस के कंस्ट्रक्टर के अंदर बुला रहा हूं, इसलिए मैं कैमरे को इनिशियलाइज़ कर सकता हूं और हर नए फ्रेम को कैप्चर करने और इसे प्रोसेस करने के लिए अपना क्लैस का तरीका पास कर सकता हूं।

मेरी विधि मेरी कक्षा में परिभाषित है।

public class Camera
{
public:
.....
void TakePicture(string pictureFileName);
void StartRecording(string videoFileName);
void StopRecording(void);
 .....
private:
volatile bool takePictureFlag;
volatile bool startRecordingFlag;
volatile bool stoptRecordingFlag;
void __stdcall TransferEndCallback(HANDLE hCamera, DWORD dwFrameNo, DWORD dwWidth, DWORD dwHeight, WORD wColorArray, PBYTE pbyteRaw, PVOID pvContext);
};

अगर मैं यह कोशिश करूँ:

StTrg_SetTransferEndCallback(cameraHandle, TransferEndCallback, NULL);

या यह:

StTrg_SetTransferEndCallback(cameraHandle, this->TransferEndCallback, NULL)

विजुअल स्टूडियो 2013 कहता है:

त्रुटि C3867: 'MyNamespace :: MyClass :: TransferEndCallback': फ़ंक्शन कॉल लापता तर्क सूची; सदस्य को पॉइंटर बनाने के लिए '& MyNamespace :: MyClass :: TransferEndCallback' का उपयोग करें

इसलिए मैं इसे सुझाव के रूप में उपयोग करता हूं:

StTrg_SetTransferEndCallback(cameraHandle, &MyNamespace::MyClass::TransferEndCallback, NULL)

और मुझे यह त्रुटि संदेश प्राप्त हुआ:

त्रुटि C2664: 'BOOL StTrg_SetTransferEndCallback (HANDLE, funcTransferEndCallback, PVOID): तर्क 2 को' शून्य (___ddall MyNamespace :: MyClass :: *) (HANDLE, DWORD, DWORD, DWORD, DWORD) से परिवर्तित नहीं कर सकता है। funcTransferEndCallback 'कोई संदर्भ नहीं है जिसमें यह रूपांतरण संभव है

तो, क्या फ़ंक्शन के रूप में सदस्य विधि पारित करना संभव है? क्या यह std::bind का मामला है?

0
Michel Feinstein 4 पद 2015, 20:55

3 जवाब

सबसे बढ़िया उत्तर

सामान्य पैटर्न उदाहरण सूचक this को PVOID pvContext पैरामीटर में पास करना है, फिर कॉलबैक के भीतर इसका उपयोग एक सदस्य फ़ंक्शन को कॉल करने के लिए करें।

public class Camera
{
// ...
void ThisTransferEndCallback(HANDLE hCamera, DWORD dwFrameNo, DWORD dwWidth, DWORD dwHeight, WORD wColorArray, PBYTE pbyteRaw);
static void __stdcall TransferEndCallback(HANDLE hCamera, DWORD dwFrameNo, DWORD dwWidth, DWORD dwHeight, WORD wColorArray, PBYTE pbyteRaw, PVOID pvContext);
};

के रूप में कॉलबैक सेट करें

StTrg_SetTransferEndCallback(cameraHandle, TransferEndCallback, this);

फिर इसे सदस्य फ़ंक्शन को भेजने के लिए स्थिर कॉलबैक लिखें

void __stdcall Camera::TransferEndCallback(HANDLE hCamera, DWORD dwFrameNo, DWORD dwWidth, DWORD dwHeight, WORD wColorArray, PBYTE pbyteRaw, PVOID pvContext)
{
    ((Camera *)pvContext)->ThisTransferEndCallback(hCamera, dwFrameNo, dwWidth, dwHeight, wColorArray, pbyteRaw);
}

उपरोक्त में त्रुटि जाँच आदि शामिल नहीं है।

2
dxiv 4 पद 2015, 18:51

इंटरफ़ेस को function कॉलबैक की आवश्यकता है। {{एक्स 1}} का अर्थ है कि non-member फ़ंक्शन या static फ़ंक्शन। ऐसा इसलिए है क्योंकि इन दोनों प्रकार के कार्यों को वर्ग वस्तु के उदाहरण की आवश्यकता के बिना लागू किया जाता है। एक वर्ग के सदस्य कार्यों को अलग तरीके से लागू किया जाता है और एक वर्ग वस्तु के उदाहरण की आवश्यकता होती है।

यदि आपको अधिक स्पष्टीकरण की आवश्यकता है, तो अन्य इस बात पर विस्तार से बता सकते हैं कि कैसे, हुड के तहत, सदस्य कार्य कॉल होते हैं।

2
Anon Mail 4 पद 2015, 18:45
StTrg_SetTransferEndCallback(cameraHandle, &MyNamespace::MyClass::TransferEndCallback, NULL)

यह काम नहीं करेगा, क्योंकि विधि को कॉल करने के लिए कोई वस्तु नहीं है। जैसा कि Anon Mail ने सुझाव दिया है, एक स्थिर कार्य ऐसा करने का सबसे अच्छा तरीका है। लेकिन, आपने कहा था कि आप ऐसा नहीं कर सकते।

मेरा सुझाव है कि अपनी कक्षा को एक सिंगलटन में रिफ्लेक्टर करें और एक स्थिर फॉरवर्ड-फंक्शन जोड़ें। उदाहरण:

public class Camera
{
public:
static *Camera the()
{
  if (!singleton)
    singleton = new Camera;
  return singleton;
}
void destroy() { delete singleton; singleton = nullptr; }
 .....
private:
static void TransferEndCallbackForward(HANDLE hCamera, DWORD dwFrameNo, DWORD dwWidth, DWORD dwHeight, WORD wColorArray, PBYTE pbyteRaw, PVOID pvContext)
{
  assert(singleton != nullptr); // Implement your own error handling here
  singleton->TransferEndCallback(hCamera, dwFrameNo, dwWidth, dwHeight, wColorArray, pbyteRaw, pvContext);
}
void __stdcall TransferEndCallback(HANDLE hCamera, DWORD dwFrameNo, DWORD dwWidth, DWORD dwHeight, WORD wColorArray, PBYTE pbyteRaw, PVOID pvContext);
static Camera *singleton = nullptr;
};

मुझे उम्मीद है कि आपकी मदद कर सकता है।

1
Marc 4 पद 2015, 18:17