2013-02-10 25 views
9

lib गोली में एक प्रकार परिभाषित किया गया है:इसे कैसे बढ़ाया जाए :: बाइंड (& myClass :: मजेदार, यह, _1, _2, _3) टाइपपीफ शून्य (* मजेदार) (arg1, arg2, arg3) पर?

typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo); 
वहाँ डॉक्स में

वहाँ प्रस्तुत किया है एक sample of usage (page 23):

void MyNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo) { 
     // Do your collision logic here 
     // Only dispatch the Bullet collision information if you want the physics to continue 
     dispatcher.defaultNearCallback(collisionPair, dispatcher, dispatchInfo); 
} 

मैं तो मेरी कक्षा इस समारोह मिला मेरी कक्षा defention में इस नमूना कोड की नकल की और

dispatcher->setNearCallback(boost::bind(&BulletAPIWrapper::MyNearCallback, this, _1, _2, _3)); 
बजाय सी की तरह

dispatcher->setNearCallback(MyNearCallback); गोली ट्यूटोरियल से: मैं की तरह इस तरह के डाले करने के लिए सक्षम हो जाएगा।

Error 44 error C2664: 'btCollisionDispatcher::setNearCallback' : cannot convert parameter 1 from 'boost::_bi::bind_t<R,F,L>' to 'btNearCallback' 

तो मुझे आश्चर्य है कि इस तरह के typedef को बढ़ावा :: बाँध कास्ट करने के लिए कैसे:

फिर भी मेरी VS2010 SP1 मुझे एक त्रुटि देता है?

यह संभव होने स्थिर वर्ग समारोह चल रहा है (या की तरह कम से कम वैश्विक समारोह में):

void MyNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo, BulletAPI* api) { 
} 

कॉल dispatcher->setNearCallback(boost::bind(MyNearCallback, _1, _2, _3, this));

क्योंकि यह मेरे लिए लगभग एक ही त्रुटि परिणाम:

Error 44 error C2664: 'btCollisionDispatcher::setNearCallback' : cannot convert parameter 1 from 'boost::_bi::bind_t<R,F,L>' to 'btNearCallback' 

मैंने as described here:

भी कोशिश की 210

अभी तक मैं ऐसे त्रुटि इसे से बाहर हो गया:

error C2664: 'btCollisionDispatcher::setNearCallback' : cannot convert parameter 1 from 'void (__cdecl *)(btBroadphasePair &,btCollisionDispatcher &,const btDispatcherInfo &)' to 'btNearCallback' 
+2

एक ही रास्ता मैं के बारे में पता जटिल और कष्टप्रद है, इसलिए +1, हो सकता है किसी को एक और संभावना को उजागर कर सकते हैं। –

+2

इसी तरह के प्रश्न ... अभी तक एकमात्र संकल्प "एक छोटा रैपर लिखें" है: http://stackoverflow.com/questions/13238050 या http://stackoverflow.com/questions/10555464 या http://stackoverflow.com/प्रश्न/10938774 –

उत्तर

8

तुम्हें क्या लगता है आप "की तरह कास्ट करने के लिए सक्षम होना चाहिए .." करते हैं? SetNearCallback निश्चित रूप से एक सामान्य फ़ंक्शन पॉइंटर को पारित करने की अपेक्षा करता है, जबकि BIND कुछ पूरी तरह से अलग करता है ..

तथ्य यह है कि बाइंड एक "कॉल करने योग्य चीज़" उत्पन्न करता है जिसे "पॉइंटर" की आवश्यकता नहीं होती है इसका मतलब यह नहीं है कि इसमें एक सादा समारोह का उत्पादन किया!

बाध्य सदस्य फ़ंक्शंस को सही तरीके से संभालने के लिए आपको अभी भी कम से कम दो पॉइंटर्स की आवश्यकता है, जबकि सामान्य फ़ंक्शन पॉइंटर एक पॉइंटर होता है। सभी सेन *) एपीआई जो आपको कॉलबैक पंजीकृत करने की अनुमति देती हैं, आपको कॉलबैक के साथ कुछ 'उपयोगकर्ता डेटा' पास करने की अनुमति भी देती है - ऐसे मामलों में आप छोटे रैपर बनाने के लिए इसका उपयोग कर सकते हैं जो कॉल को आपके बाध्य सदस्य फ़ंक्शन पर रीडायरेक्ट करेगा। इस पर कई स्थानों पर चर्चा की गई है .. कृपया उदाहरण के लिए देखें: https://stackoverflow.com/a/3453616/717732

यदि आप कॉलबैक के साथ कोई अतिरिक्त डेटा पास नहीं कर सकते हैं, तो मेरा मतलब है, अगर कॉलबैक पंजीकरण आपको केवल कॉलबैक पॉइंटर प्रदान करने की अनुमति देता है, तो यह है लगभग मृत अंत। आप तब तक नहीं बच सकते जब तक कि आप या तो कम या कम बदसूरत या जोखिम भरा कामकाज करते हैं। वैश्विक स्थैतिक डेटा या गतिशील कोड पीढ़ी ..

*) यह पूरी तरह से व्यक्तिगत दृष्टिकोण है। 'सेन' से मेरा मतलब है 'वस्तु-अनुकूल'। निम्न-स्तरीय एपीआई अक्सर कड़ाई से होने के लिए नहीं हैं, बल्कि वे संसाधन-संरक्षण के रूप में संभव होने की कोशिश करते हैं - और इसलिए यह आपको गंदे काम करने के लिए मजबूर करता है, क्योंकि वे वास्तव में उन 4/8 बाइट्स को सहेजना चाहते थे।कभी-कभी, कभी-कभी, इसका असर बहुत बड़ा प्रभाव पड़ता है - वे 4/8 बी कॉलबैक को आसान बना सकते हैं, यह एक ही रजिस्टर में फिट बैठता है (जबकि पॉइंटर + उपयोगकर्ताडाटा 2+ रजिस्टर्स लेता है), इसके संचालन "अधिक परमाणु हैं "आदि। हालांकि, यह अक्सर पर किया जाता है दर्दनाक रूप से हाइलाइट करता है कि केवल कॉलबैक पंजीकृत होने के लिए संभव है। ऐसे मामलों में, यह वास्तव में आपको बहुत कम अंतर बनाता है, भले ही यह किसी ऑब्जेक्ट के सदस्य कार्य को बाध्य करेगा, या सिर्फ एक वैश्विक स्थैतिक कार्य होगा: बिलकुल भी, केवल एक ही हो सकता है, इसलिए, जो भी हो, बस इसे काम करें। यदि यह मामला है, तो ऑब्जेक्ट पॉइंटर और छोटे रैपर के लिए केवल वैश्विक स्थैतिक चर का उपयोग करें। ठीक है, सौंदर्यशास्त्र के अलावा ..:

static MyObject* target; 
void wrapper(..params..) 
{ 
    target->method_to_be_called(..params..); 
} 

// then, register it: 

target = &object_to_be_called; // \ there can be only one object 
setCallback(&wrapper);   ///and only one callback registered 
इस प्रश्न के लिए