दिलचस्प पोस्ट
ओपनसीवी में उलटा फूरियर रूपांतरण साक्षात्कार: जावा बराबर फ़ाइल में अंतर। पथ और पथ में स्लैश कॉलकॉन्टेक्स्ट बनाम थ्रेडस्टैटिक कोशिश की और सी में सरल सरल फ़ाइल कॉपी कोड? सी ++ मिक्सन-स्टाइल क्या है? स्काला 2.8 के लिए कौन सा आईडीई? इम्यूलेटर: त्रुटि: x86 इम्यूलेशन वर्तमान में हार्डवेयर त्वरण की आवश्यकता है सी / सी ++ के लिए बहुस्तृत मेमोरी आबंटक Jquery AJAX फ़ॉर्म सबमिट सबमिट करें जावा में एएससीआईआई से ईबीसीडीआईसी से स्ट्रिंग को परिवर्तित करें? बैकबोन.जेएस संरचना नेस्टेड दृश्य और मॉडल पायथन कैसे पाइप काम करता है? Jquery का उपयोग करते हुए html तालिकाओं से एक्सेल शीट उत्पन्न करें JQuery का उपयोग करके क्लिक करने पर एंकर टेक्स्ट / href कैसे प्राप्त करें?

सी ++ में, क्या यह सीआईडी ​​कॉलबैक के लिए स्थिर सदस्य फ़ंक्शन पॉइंटर का उपयोग करने के लिए सुरक्षित / पोर्टेबल है?

सी ++ में, क्या यह सीआईडी ​​कॉलबैक के लिए स्थिर सदस्य फ़ंक्शन पॉइंटर का उपयोग करने के लिए सुरक्षित / पोर्टेबल है? क्या एक स्थिर सदस्य की एबी सी फ़ंक्शन के समान है?

Solutions Collecting From Web of "सी ++ में, क्या यह सीआईडी ​​कॉलबैक के लिए स्थिर सदस्य फ़ंक्शन पॉइंटर का उपयोग करने के लिए सुरक्षित / पोर्टेबल है?"

यह सी ++ मानक प्रति सुरक्षित नहीं है जैसा कि इस तरह से पोस्टिंग में कहा गया है:

सी ++ में लागू एसी कॉलबैक फ़ंक्शन extern "C" होना चाहिए ऐसा लगता है कि यह कक्षा में एक स्थिर कार्य के रूप में काम करता है क्योंकि क्लास-स्टैटिक फंक्शंस अक्सर एक समान कॉलिंग सम्मेलन का उपयोग सी फंक्शन के रूप में करते हैं। हालांकि, ऐसा करने से एक बग होने का इंतजार है (नीचे टिप्पणियां देखें), इसलिए कृपया नहीं – इसके बजाय एक extern "C" आवरण के माध्यम से जाना।

और उत्तर में मार्टिन यॉर्क द्वारा की गई टिप्पणियों के अनुसार कुछ प्लेटफार्मों पर ऐसा करने की वास्तविक दुनिया समस्याएं हैं।

अपने सी एबीआई कॉलबैक को extern "C" बनाएं


संपादित करें: मानक (जोर खान) से कुछ सहायक उद्धरण जोड़ना:

3.5 "कार्यक्रम और संबंध":

सभी प्रकार के समायोजन के बाद (जिनके दौरान टाइपफीफेस (7.1.3) उनकी परिभाषाओं द्वारा प्रतिस्थापित किया गया है), किसी दिए गए ऑब्जेक्ट या फ़ंक्शन का जिक्र करते हुए सभी घोषणापत्रों द्वारा निर्दिष्ट प्रकार समान होंगे , सिवाय एक सरणी ऑब्जेक्ट के लिए यह घोषणा ऐरे प्रकार निर्दिष्ट कर सकती है एक प्रमुख सरणी की उपस्थिति या अनुपस्थिति से अलग (8.3.4)। टाइप नियम पर इस नियम का उल्लंघन किसी नैदानिक ​​की आवश्यकता नहीं है। [3.5 / 10]

[नोट: लिंकेज को गैर-सी ++ घोषणाएं एक लिंक-विनिर्देशन (7.5) का उपयोग करके प्राप्त की जा सकती हैं। ] [3.5 / 11]

तथा

7.5 "लिंकेज विनिर्देश":

… विभिन्न भाषा संबंधों के साथ दो फ़ंक्शन प्रकार अलग- अलग प्रकार होते हैं, भले ही वे अन्यथा समान हों। [7.5 / 1]

इसलिए यदि कॉलबैक कॉलबैक कॉलबैक के लिए सी भाषा बाइंडिंग का उपयोग कर रहा है, तो कॉलबैक लक्ष्य (सी ++ प्रोग्राम में) के रूप में भी होना चाहिए।

खोज के बाद और अन्य समस्याओं पर हमला करते हुए कई ब्रेक, मुझे एक जवाब मिला जो स्पष्ट और संक्षिप्त (मानक के लिए, वैसे भी):

एक अभिव्यक्ति के माध्यम से किसी फ़ंक्शन को कॉल करना जिसका फ़ंक्शन प्रकार में एक भाषा का लिंक होता है जो कि फ़ंक्शन प्रकार की फ़ंक्शन प्रकार की भाषा लिंकेज से भिन्न है, परिभाषित नहीं है [5.2.2 / 1]

मैं अभी भी इसे बनाए रखता हूं कि सी ++ मानक से पाठ का उपयोग करने के लिए एक सी लाइब्रेरी के व्यवहार को सी कम्पाइलर के साथ संकलित करने के लिए मूलभूत स्तर पर समस्यात्मक समस्या है, और वास्तव में अंतर-भाषा में अंतर कैसे कार्य करता है यह बहुत कार्यान्वयन-विशिष्ट है; हालांकि, यह निकटतम मुझे लगता है कि या तो मानक (वर्तमान में) ऐसी बातचीत को परिभाषित करने की उम्मीद कर सकता है।

विशेष रूप से, यह अपरिभाषित व्यवहार (और सी लाइब्रेरी का उपयोग नहीं कर रहा है ताकि समस्या उत्पन्न न हो):

 void call(void (*pf)()) { pf(); } // pf() is the UB extern "C" void f(); int main() { call(f); } // though I'm unsure if a diagnostic is required for call(f) 

कमो call(f) निदान call(f) (हालांकि यह ऐसा कर सकता है कि भले ही नैदानिक ​​की आवश्यकता नहीं है)

यह अपरिभाषित व्यवहार नहीं है, और यह दर्शाता है कि फंक्शन सूचक प्रकार (जो कि टाइप टाइपफे के माध्यम से होता है) में भाषा लिंकेज को शामिल करना है:

 extern "C" typedef void F(); void call(F* pf) { pf(); } extern "C" void f(); int main() { call(f); } 

या लिखा जा सकता है:

 extern "C" { typedef void F(); void f(); } void call(F* pf) { pf(); } int main() { call(f); } 

सभी Windows C ++ कंपाइलर के लिए मुझे पता है, जवाब हाँ है, लेकिन भाषा मानक में कुछ भी यह गारंटी नहीं देता है मैं आपको यह रोक नहीं दूँगा लेकिन, सी ++ का उपयोग करते हुए कॉलबैक को लागू करने का यह एक बहुत ही आम तरीका है – आपको मिल सकता है कि आपको स्थिर कार्यों को डब्ल्यूआईएनपीआई के रूप में घोषित करना होगा, हालांकि इसे अपने स्वयं के पुराने थ्रेडिंग लाइब्रेरी से लिया गया है:

 class Thread { ... static DWORD WINAPI ThreadFunction( void * args ); }; 

जहां यह ते विंडोज थ्रेडिंग एपीआई द्वारा कॉलबैक उपयोग है

एबी सी या सी ++ मानकों द्वारा कवर नहीं है, भले ही C ++ आपको extern "C" माध्यम से "भाषा लिंकेज" दे। इसलिए, एबीआई मौलिक संकलक / प्लेटफ़ॉर्म विशिष्ट है दोनों मानकों के कार्यान्वयन के लिए कई, कई चीजें छोड़ देते हैं, और यह उनमें से एक है।

नतीजतन, 100% पोर्टेबल कोड-या स्विचिंग कंपाइलर-लिखना असंभव है, लेकिन विक्रेताओं और उपयोगकर्ताओं को उनके विशिष्ट उत्पादों में काफी लचीलेपन की अनुमति देता है। इस लचीलेपन से अधिक स्थान और समय कुशल कार्यक्रमों की अनुमति मिलती है, ऐसे तरीकों से जिन्हें मानक समितियों द्वारा अग्रिम रूप से अनुमानित नहीं करना पड़ता है।


जैसा कि मैं समझता हूं, आईएसओ के नियम हर 10 सालों से अधिक बार एक मानक की अनुमति नहीं देते हैं (लेकिन सीईसी के लिए टीसी 1 और टीआर 1 जैसे विभिन्न प्रकाशन हो सकते हैं)। इसके अलावा, विचार (मुझे यकीन नहीं है कि यह आईएसओ से आता है, सी कमेटी से किया जाता है, या फिर कहीं से भी) के लिए छोड़ दिया क्षेत्र में जाने की बजाय मौजूदा अभ्यास को "डिस्टिल्ड" / मानकीकृत करने के लिए, और बहुत सारे हैं मौजूदा प्रथाओं, जिनमें से कुछ संघर्ष