2011-10-25 10 views
5

लघु संस्करण: मेरे पास एक क्यूटी/सी ++ है जिसमें मुझे कोको/ऑब्जेक्टिव-सी कोड की सीमित मात्रा जोड़नी है। मैंने .cpp फ़ाइल को .mm फ़ाइल में बदल दिया है और ऑब्जेक्ट-सी कोड/ऑब्जेक्ट्स को फ़ाइल में जोड़ा है, और यह संकलित करता है और काम करता है। अब मुझे बनाए गए ऑब्जेक्ट्स में से एक के लिए एक प्रतिनिधि की आवश्यकता है- एक एनएसपीओपअप बटन (या इसके बजाए, इसके मेनू) सटीक होने के लिए - और मैं अटक गया हूं। मैं इस ऑब्जेक्ट के लिए एक प्रतिनिधि कैसे जोड़ सकता हूं?सी ++ से उद्देश्य-सी प्रतिनिधिमंडल को कैसे संभालें?

विवरण: प्रश्न में फ़ाइलें:

reportwindow.h, reportwindow.cpp -These reportwindow.mm का नाम बदलकर अपने मूल सी ++ कार्यान्वयन युक्त फ़ाइलों प्लस कुछ उद्देश्य-सी कोड (खोलने एक NSSavePanel एक युक्त हैं NSPopUpButton)। reportwindow.h अतिरिक्त रूप से एक .cpp फ़ाइल में शामिल है, अगर इससे कोई फर्क पड़ता है।

menuHandler.h, menuHandler.mm -These फ़ाइलें एक (वर्तमान में खाली) उद्देश्य-सी वर्ग है कि मैं एक प्रतिनिधि

मेरी पहली सोचा था कि मैं बस सी बना सकता है के रूप में उपयोग करने के लिए इच्छुक था शामिल ++ वर्ग प्रतिनिधि, लेकिन यह स्पष्ट रूप से काम नहीं करता है क्योंकि सी ++ प्रतिनिधिमंडल को समझ में नहीं आता है। मैंने सोचा कि मैं एक अलग उद्देश्य-सी वर्ग को एनएसएमएनयू डीलेगेट के रूप में बनाउंगा और इसके सी ++ वर्ग में सदस्य ऑब्जेक्ट के रूप में इसका एक उदाहरण जोड़ूंगा। चूंकि मैं सदस्यों के रूप में अन्य उद्देश्य-सी वस्तुओं को जोड़ने में सक्षम हूं, मुझे लगा कि यह काम करना चाहिए। हालांकि, जैसे ही मैंने सी ++ क्लास हेडर फ़ाइल में अपने नए उद्देश्य-सी वर्ग के लिए हेडर शामिल किया, मुझे एप्पल हेडर फ़ाइलों (NSValue.h से) "अपेक्षित अयोग्यता-आईडी से पहले '@' टोकन" के बारे में कई सौ त्रुटियां मिलीं। , NSObject.h, आदि) तो जाहिर है कि काम नहीं किया, कम से कम नहीं है। मुझे एक ही परिणाम मिलता है जब मेरी कक्षा शीर्षलेख फ़ाइल में कोई भी कोको हेडर शामिल होता है।

मैंने सोचा कि मैं उद्देश्य-सी वर्ग की अग्रेषित घोषणा की कोशिश करूंगा (इस तरह मैं अन्य उद्देश्य-सी वस्तुओं को काम कर रहा हूं)। हालांकि, यह या तो काम नहीं करता- अगर मैं इसे "क्लास myClassName" के रूप में घोषित करता हूं तो मुझे वर्ग को एक अलग प्रकार के प्रतीक के रूप में परिभाषित करने में त्रुटि मिलती है (संभवतः सी ++ कक्षा बनाम उद्देश्य-सी प्रोटोकॉल)। अगर मैं इसे @protocol myClassName के रूप में घोषित करने का प्रयास करता हूं, तो मुझे "अपेक्षित अयोग्यता-आईडी पहले '@' टोकन" के बारे में एक त्रुटि मिलती है। तो मैं यह काम कैसे कर सकता हूं?

+0

में आप मिमी के लिए है कि विशिष्ट cpp फ़ाइल का नाम बदला है पर कुछ उपयोगी जानकारी नहीं है? –

+0

प्रश्न में हेडर से जुड़ा एक, हां। – ibrewster

+0

दूसरी तरफ जाने का रास्ता है, और शायद एकमात्र। पहली असफल कोशिश के बाद आपको आत्मसमर्पण नहीं करना चाहिए। अधिक जानकारी प्रदान करें, इसमें क्या शामिल है, वहां और अधिक .cpp फ़ाइलें हो सकती हैं जिनमें 'reportwindow.h' शामिल है। – hamstergene

उत्तर

10

ठीक है आपके सवाल का जवाब देना:

reportwindow.h इसके अतिरिक्त, एक .cpp फ़ाइल में शामिल है कि अगर कुछ फ़र्क पड़ता है।

इससे कोई फर्क पड़ता है। उद्देश्य-सी कोड को छूने वाला कोई भी संकलन इकाई (इस मामले में सीपीपी फ़ाइल) का नाम बदलकर .mm या .m कर दिया जाना चाहिए। उस हेडर को शामिल करना जिसमें सी ++ फ़ाइल में ऑब्जेक्टिव-सी सामान शामिल है, उस समस्या का कारण बन जाएगा जिससे सी ++ कंपाइलर उद्देश्य-सी कोड देखता है जिसे वह संभाल नहीं सकता है।

मिमी में सीपीपी फ़ाइल का नामकरण संकलन के दौरान उद्देश्य-सी विकल्प का चयन करेगा (जो फ़ाइल को सीपीपी या सी नामित नहीं किया जाता है) और इसलिए उद्देश्य-सी टोकन के साथ सामान संकलित करने की अनुमति देता है (मुख्य रूप से "@" आपके मामले में)।

एक विकल्प आपके सी ++ वर्ग में उद्देश्य-सी प्रतिनिधि वर्ग को शामिल नहीं करना होगा, बल्कि उद्देश्य-सी प्रतिनिधि के भीतर अपने सी ++ वर्ग में एक पॉइंटर शामिल करना होगा (यानी इसे अन्य तरीकों से लागू करें)। इस तरह आप चीजें व्यवस्थित कर सकते हैं कि उद्देश्य-सी कोड C++ कोड को छू नहीं रहा है।

संपादित करें: असल में, मैं दूसरा सुझाव पसंद करूंगा। यहां एक उदाहरण दिया गया है:

DelegateClass।ज:

class MyCPPClassHandlingStuff; 

@interface MyDelegateObject : NSObject <SomeDelegateProtocol> { 
    MyCPPClassHandlingStuff *m_handlerInstance; 
} 

- (id) initWithCPPInstance:(MyCPPClassHandlingStuff*)cppInstance; 

- (void) theDelegateProtocolMethod; 

@end 

DelegateClass.mm

#include "MyCPPClassHandlingStuff.h" 

@implementation MyDelegateObject 

- (id) initWithCPPInstance:(MyCPPClassHandlingStuff*)cppInstance 
{ 
    self = [super init]; 
    if (self) { 
    m_handlerInstance = cppInstance; 
    } 
    return self; 
} 

- (void) theDelegateProtocolMethod 
{ 
    if (m_handlerInstance) 
    m_handlerInstance->handleDelegateMethod(); 
} 

@end 

और अच्छी तरह से MyCPPClassHandlingStuff.h:

#ifndef __MyCPPClassHandlingStuff_H__ 
#define __MyCPPClassHandlingStuff_H__ 

class MyCPPClassHandlingStuff 
{ 
public: 
    MyCPPClassHandlingStuff(); 
    void handleDelegateMethod(); 
}; 

#endif /* __MyCPPClassHandlingStuff_H__ */ 

MyCPPClassHandlingStuff ऑब्जेक्टिव-सी से प्रारंभ किया जा सकता है लेकिन आप किसी भी ऑब्जेक्टिव-सी वर्ग आरंभ नहीं कर सकते सी ++ कोड से वहां। यदि आपको अपने सी ++ कोड में ऑब्जेक्टिव-सी का उपयोग करने की आवश्यकता है, तो आपको इसे उद्देश्य-सी के रूप में संकलित करना होगा (यानी। .mm फ़ाइल का उपयोग करें)। मैं पाठक के लिए एक व्यायाम के रूप सीपीपी विवरण छोड़;)

+1

क्या आप कृपया .cpp कार्यान्वयन का विचार भी दे सकते हैं: पी आप MyDelegateObject को कैसे प्रारंभ करेंगे सीपीपी। – Aalok

0

मैं तो सोचा था कि मैं (ऑब्जेक्टिव-सी वर्ग के एक आगे की घोषणा की कोशिश करता हूँ वह यह है कि मैं कैसे अन्य उद्देश्य-सी वस्तुओं काम कर मिल गया)। हालांकि, यह या तो काम नहीं करता- अगर मैं इसे "क्लास myClassName" के रूप में घोषित करता हूं तो मुझे वर्ग को एक अलग प्रकार के प्रतीक के रूप में परिभाषित करने में त्रुटि मिलती है (संभवतः सी ++ कक्षा बनाम उद्देश्य-सी प्रोटोकॉल)।

आगे क्यों न दें- इसे @class myClassName के रूप में घोषित करें?

+0

मैंने कोशिश की, उसने "अपेक्षित अयोग्यता-आईडी से पहले '@ प्रतीक के बारे में त्रुटियां दीं। बाहर निकलता है क्यूटी एक moc_ .cpp फ़ाइल उत्पन्न कर रहा था जो चीजों को फेंक रहा था। इस मुद्दे को हल करने के लिए .mm ने इसका नाम बदल दिया। – ibrewster

0

प्रतिनिधि प्रोटोकॉल को संतुष्ट करने के लिए एक उद्देश्य-सी कक्षा बनाएं, और इसे अपने सी ++ वर्ग में प्रतिनिधि दें। समस्या यह है कि ऐपकिट ऑब्जेक्टिव-सी ऑब्जेक्ट्स से बात करने की अपेक्षा करता है, इसलिए आपको अपने सी ++ ऑब्जेक्ट्स को प्रतिनिधि करने के लिए एक शिम की आवश्यकता है। (हां आप कुछ रनटाइम दुर्व्यवहार कर सकते हैं, जो आपके सी ++ वर्ग में आईएसए पॉइंटर को परिभाषित कर सकता है ताकि इसे ओबीजेसी ऑब्जेक्ट्स (उस बिंदु पर जहां आप सी ++ कक्षाओं को संदेश भेज सकें) के साथ कुछ हद तक संगत बना सकें, लेकिन ऐसा न करें। यह बुरा है।)

तो अपनी सी ++ कक्षा के साथ शुरू किया गया एक शिम बनाएं, यह एक ivar के रूप में है। इसे आपके द्वारा रुचि रखने वाली प्रतिनिधि विधियों को लागू करना चाहिए, और उनको अपने सी ++ वर्ग के साथ इस तरह से पारित करना चाहिए कि यह समझ सके। तादा, किया।

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