2012-06-28 13 views
7

मेरे पास सी ++ में लिखा गया मल्टीप्लेटफार्म गेम है। मैक संस्करण में, भले ही मेरे पास कोई ओबीजे-सी कोड न हो, फिर भी मेरे द्वारा उपयोग की जाने वाली पुस्तकालयों में से एक ऑटो-रिलीजिंग सामान प्रतीत होता है, और इसके लिए मुझे स्मृति रिसाव मिलती है, क्योंकि मैंने एनएसएयूटोरिलीजूल नहीं बनाया है।उद्देश्य-सी के बिना NSAutoreleasePool कैसे बनाएं?

जो मैं चाहता हूं वह obj-c कोड का उपयोग किये बिना एक NSAutoreleasePool बनाने (और नष्ट) करने में सक्षम होना है, इसलिए मुझे एक .m फ़ाइल बनाने की आवश्यकता नहीं है, और इसके लिए मेरी बिल्ड स्क्रिप्ट को बदलना है। क्या यह संभव है? वह कैसे किया जा सकता है?

ओबीएस: टैग की गई सी और सी ++, क्योंकि इनमें से किसी भी भाषा में समाधान होगा।

+0

क्या आपकी समस्या कोई उद्देश्य-सी कोड लिख रही है? या जब आप केवल .c/.cpp चाहते हैं तो अपनी प्रोजेक्ट में .m फ़ाइलें हैं? – Sean

+1

ध्यान दें कि @ abarnert का कोड एक व्यावहारिक समाधान है, जबकि यह लाइब्रेरी में एक बग इंगित करता है। कोई सी या सी ++ फ़ंक्शन एक ऑटोरेलीज पूल उत्पन्न किए बिना ओबीजेसी कोड में कॉल करना चाहिए। यदि यह ऐप्पल कोड है, तो आपको bugreport.apple.com पर एक रडार खोलना चाहिए। –

+0

@ सेन मैं केवल .c/.cpp फ़ाइलों को चाहता हूं। मुझे पता है कि मैं उन फ़ाइलों को अन्य प्लेटफार्मों के निर्माण में शामिल कर सकता हूं, लेकिन मैं इससे बचने की कोशिश कर रहा हूं। – fbafelipe

उत्तर

2

आप उद्देश्य-सी रनटाइम को तुरंत चालू करने से नहीं बच सकते-लेकिन जाहिर है कि आप पहले से ही उनमें से एक प्राप्त कर चुके हैं।

यदि आप सी से रनटाइम के साथ बातचीत करना चाहते हैं, तो आप हमें उद्देश्य-सी रनटाइम एपीआई बना सकते हैं, जैसा कि Objective-C Runtime Programming Guide और Objective-C Runtime Reference में प्रलेखित है।

#include <objc/runtime.h> 
#include <objc/objc-runtime.h> 
id allocAndInitAutoreleasePool() { 
    Class NSAutoreleasePoolClass = objc_getClass("NSAutoreleasePool"); 
    id pool = class_createInstance(NSAutoreleasePoolClass, 0); 
    return objc_msgSend(pool, "init"); 
} 
void drainAutoreleasePool(id pool) { 
    (void)objc_msgSend(pool, "drain"); 
} 

आप किसी अन्य फ़ाइल से इन कार्यों कॉल करना चाहते हैं, तो बेशक आप वहाँ ObjC/runtime.h शामिल करने के लिए और साथ ही होगा:

विचार यह (untested) की तरह कुछ है। या, वैकल्पिक रूप से, आप allocAndInit फ़ंक्शन से वापसी में आईडी को शून्य * पर डाल सकते हैं, और एक शून्य * ले सकते हैं और नाली फ़ंक्शन में आईडी पर वापस डाला जा सकता है। (आप स्ट्रक्चर objc_object और typedef struct objc_object * id को भी अग्रेषित कर सकते हैं, लेकिन मेरा मानना ​​है कि वास्तव में सही परिभाषा होने की गारंटी नहीं है।)

आपको अपने लिंक कमांड में -lobjc पास नहीं करना चाहिए।

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

+2

आपको रनटाइम फ़ाइलों को शुद्ध सी कोड के साथ लोड करने में सक्षम होना चाहिए (बिना '-lobjc' की आवश्यकता के)। आप यहां इसका एक उदाहरण देख सकते हैं: https://github.com/rnapier/ios5ptl/blob/master/ch20/Runtime/MyMsgSend.c (मैं अनुशंसा नहीं कर रहा हूं कि आप 'myMsgSend()' का उपयोग करें, यह एक प्रदर्शन है कुछ और। मैं सिर्फ एक संकलित सी फ़ाइल दिखा रहा हूं जो इस दृष्टिकोण को दिखाता है।) –

+1

एक साइड-नोट के रूप में, जबकि '.m' फ़ाइलें ठीक हो सकती हैं, मैं अनुशंसा नहीं करता कि आप इस समस्या के आसपास काम करते हैं। बहुत छोटी रैपर को छोड़कर एमएम' फाइलें। ObjC++ कई समस्याओं का कारण बनता है। यह गोंद के एक छोटे टुकड़े के रूप में ठीक है, और यह इस समस्या को हल करने का एक अच्छा तरीका है (कॉल को शुद्ध सी या सी ++ हेडर और कॉल के आस-पास @autorelease {} के साथ थोड़ा '.mm' फ़ंक्शन में कॉल करें)। लेकिन अपने सी ++ शुद्ध और अपने ओबीजेसी शुद्ध रखें। –

+0

@RobNapier: -lobjc पर नोट के लिए धन्यवाद। मैं जवाब अपडेट करूंगा। – abarnert

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