2009-05-13 21 views
6

मैं सिम्बियन प्लेटफ़ॉर्म पर एक सी ++ मोबाइल फोन एप्लिकेशन विकसित करने में व्यस्त हूं। आवश्यकता में से एक है कि इसे सभी सिम्बियन फोन पर दूसरे संस्करण फोन से सीधे 5 वें संस्करण फोन पर काम करना है। अब संस्करणों में सिम्बियन एसडीके में अंतर हैं।प्रीप्रोसेसर निर्देशों के विकल्प

#ifdef S60_2nd_ED 
    Code 
#elif S60_3rd_ED 
    Code 
#else 
    Code 

अब के बाद से आवेदन मैं विकासशील हूँ यह जल्द ही के दसियों बड़ा हो जाएगा तुच्छ नहीं है: मैं पूर्वप्रक्रमक निर्देशों का उपयोग करने के सशर्त कोड कि एसडीके जिसके लिए आवेदन नीचे की तरह बनाया जा रहा है के लिए प्रासंगिक हैं संकलित करने के लिए है कोड की हजारों लाइनें और उपरोक्त की तरह प्रीप्रोसेसर निर्देश पूरे फैले होंगे। मैं जानना चाहता हूं कि इसका कोई विकल्प है या इस मामले में इन प्रीप्रोसेसर निर्देशों का उपयोग करने का एक बेहतर तरीका हो सकता है।

कृपया मदद करें।

उत्तर

5

मैं वही हूं जहां आप हैं।

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

#if S60_3rd_ED 
    #define CAF_AGENT 1 
    #define HTTP_FILE_UPLOAD 1 
#elif S60_2nd_ED 
    #define CAF_AGENT 0 
    #if S60_2nd_ED_FP2 
     #define HTTP_FILE_UPLOAD 1 
    #else 
     #define HTTP_FILE_UPLOAD 0 
    #endif 
#endif 

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

हमने आपके द्वारा प्राप्त यूआई कक्षाओं के लिए भी परिभाषित किया था, ताकि एसआई 60 और UIQ के बीच कुछ यूआई कोड सामान्य हो। असल में उत्पाद की वजह से, हमारे पास यूआई से संबंधित कोड नहीं था, इसलिए इसका एक सभ्य अनुपात आम था।

जैसा कि अन्य कहते हैं, हालांकि, जहां संभव हो वहां कक्षाओं और कार्यों में परिवर्तनीय व्यवहार को झुकाव करना और विभिन्न संस्करणों को लिंक करना बेहतर है। टिप्पणी

[जवाब में संपादित करने के लिए:

हम कुछ भी संकल्प पर निर्भर कर से बचने के लिए काफी कोशिश की - सौभाग्य से विशेष एप्लिकेशन इस लिए भी मुश्किल नहीं था, इसलिए हमारे सीमित यूआई बहुत सामान्य था। मुख्य बात जहां हमने स्क्रीन रिज़ॉल्यूशन पर स्विच किया था स्प्लैश/पृष्ठभूमि छवियों और इसी तरह के लिए था। हमारे पास बिल्ड फाइलों को प्रीप्रोसेस करने के लिए एक स्क्रिप्ट थी, जिसने चौड़ाई और ऊंचाई को फ़ाइल नाम, splash_240x320.bmp या जो कुछ भी प्रतिस्थापित किया था। हम वास्तव में छवियों को हाथ से उत्पन्न करते हैं, क्योंकि वहां कई सारे आकार नहीं थे और छवियां अक्सर नहीं बदलीं। एक ही स्क्रिप्ट ने .h फ़ाइल उत्पन्न की जिसमें बिल्ड फ़ाइल निर्माण में उपयोग किए जाने वाले अधिकांश मानों की # परिभाषाएं शामिल हैं।

यह प्रति डिवाइस निर्माण के लिए है: हमारे पास अधिक सामान्य एसआईएस फाइलें भी थीं, जो कि फ्लाई पर छवियों का आकार बदलती थीं, लेकिन हमें अक्सर स्थापित आकार पर आवश्यकता होती थी (रॉम कभी-कभी सीमित था, जो महत्वपूर्ण है कि आपका ऐप हिस्सा है बेस डिवाइस छवि), और छवियों का आकार बदलना थोड़ा सा नीचे रखने का एक तरीका था। N92, Z8, आदि पर स्क्रीन रोटेशन का समर्थन करने के लिए, हमें अभी भी कुछ छवियों के चित्र और परिदृश्य संस्करणों की आवश्यकता है, क्योंकि फ़्लिपिंग पहलू अनुपात समान या समान अनुपात के आकार के रूप में अच्छे नतीजे नहीं देता है ...]

+0

अरे, क्या आप मुझे विभिन्न मोबाइल स्क्रीन संकल्पों को संभालने के लिए अपना दृष्टिकोण भी बता सकते हैं – ardsrk

15

अच्छा ... यह मतभेदों की सटीक प्रकृति पर निर्भर करता है। यदि उन्हें बाहर निकालना संभव है और उन्हें विशेष कक्षाओं में अलग करना है, तो आप उस मार्ग पर जा सकते हैं। इसका मतलब कुछ वर्गों के संस्करण-विशिष्ट कार्यान्वयन होना होगा, और यहां और वहां कुछ पंक्तियों की बजाय पूरे कार्यान्वयन को स्विच करना होगा।

आप

  • MyClass.h
  • MyClass_S60_2nd.cpp
  • MyClass_S60_3rd.cpp

और इतने पर होगा। आप कौन सी सीपीपी फ़ाइल को ऊपर के रूप में #ifdefs का उपयोग करके पूरे अंदर लपेटकर या बिल्ड-लेवल (मेकफ़ाइल या जो भी हो) पर मेरी नियंत्रण को संकलित करके संकलित करने के लिए चुन सकते हैं, जब आप विभिन्न लक्ष्यों के लिए निर्माण कर रहे हों।

परिवर्तन की प्रकृति के आधार पर, यह बहुत साफ हो सकता है।

+1

मेरा विचार ठीक ठीक। व्यवहार मतभेदों का मॉडल करने के लिए बहुरूपता। आप विरासत का उपयोग करके बहुरूपता को लागू कर सकते हैं (इस तरह आपके उत्तर में प्रस्तावित किया गया था), लेकिन लक्षण वर्गों द्वारा सुविधा प्रदान करने के साथ-साथ समेकन का उपयोग भी किया जा सकता है। – xtofl

+3

यह सबसे अच्छा तरीका है। इसके लिए क्या मतलब है निर्माण प्रणाली का उपयोग करें; 'ifdef' अनजान कोड का मार्ग है। –

1

यदि संभव हो, तो आप सभी प्लेटफ़ॉर्म के लिए एक सामान्य इंटरफ़ेस को परिभाषित करने का प्रयास कर सकते हैं। फिर, प्रत्येक प्लेटफ़ॉर्म के लिए इंटरफ़ेस को कार्यान्वित करें।

प्रीप्रोसेसर निर्देशों का उपयोग करके सही कार्यान्वयन का चयन करें।

इस तरह, आपके पास अपने कोड में कम जगहों पर प्लेटफ़ॉर्म चयन निर्देश होगा (आदर्श रूप से, एक ही स्थान पर, स्पष्ट रूप से इंटरफ़ेस घोषित करने वाली हेडर फ़ाइल में)।

कुछ इस तरह का अर्थ है:

commoninterface.h /* declaring the common interface API. Platform identification preprocessor directives might be needed for things like common type definitions */ 
platform1.c /*specific implementation*/ 
platform2.c /*specific implementation*/ 
6

हमारी कंपनी में हम पार मंच कोड (Win32/PS3/xbox के लिए gamedevelopment/आदि) का एक बहुत लिखें।
मंच से संबंधित macroses से बचने के लिए जितना संभव हो उतना हम आम तौर पर अगले कुछ चाल का उपयोग करें: मंच-अमूर्त पुस्तकालयों में

  • निकालने platfrom से संबंधित कोड विभिन्न प्लेटफार्मों भर में एक ही इंटरफ़ेस है, लेकिन एक ही कार्यान्वयन ;
  • विभिन्न प्लेटफार्मों के लिए अलग-अलग .cpp फ़ाइलों में कोड विभाजित करें (उदा: "पाइप.h", "pipe_common.cpp", "pipe_linux.cpp", "pipe_win32.cpp", ...);
  • मंच-विशिष्ट फ़ंक्शन कॉल को एकीकृत करने के लिए मैक्रोज़ और सहायक कार्यों का उपयोग करें (उदा: "# परिभाषित करें (एक्स) नींद ((एक्स)/1000u)");
  • क्रॉस-प्लेटफ़ॉर्म तृतीय-पक्ष पुस्तकालयों का उपयोग करें।
+1

आपके सुझावों के लिए बहुत ही समान नस में, आप प्रत्येक बिल्ड के लिए विशिष्ट खोज निर्देशिका भी शामिल कर सकते हैं - इसलिए #include "sound_constants.h" जैसी कुछ चीज़ उस फ़ाइल के कई क्रमिकताओं में से एक पायेगी। –

+0

अच्छी टिप! मैं कम-स्तरीय बग्स से थोड़ा डरता हूं जैसे विभिन्न संकलन इकाइयों में विसंगति संरचना घोषणाओं (# अंतर्निहित "वाक्यविन्यास रिश्तेदार बनाने के लिए अनुमति देता है जिसमें सभी अतिरिक्त और मानक निर्देशिकाओं ~ _ ~') के बीच सर्वोच्च प्राथमिकता वाले पथ शामिल हैं। हालांकि इस तरह की रक्षा करें: http://www.everfall.com/paste/id.php?xxd85sd9c38g - हेडर में ऐसी समस्याएं हल हो सकती हैं ... – Rageous

0

वैकल्पिक के बारे में कोई विचार नहीं है, लेकिन आप क्या कर सकते हैं, ओएस के विभिन्न संस्करणों के लिए अलग-अलग फ़ाइलों का उपयोग करने के लिए उपयोग करें। उदाहरण

#ifdef S60_2nd_ED

#include "graphics2"

#elif S60_3rd_ED

#include "graphics3"

#else

#include "graphics"

1

SQLite पर देखें। उन्हें एक ही समस्या है। वे प्लेटफॉर्म-निर्भर सामग्री को फ़ाइलों को अलग करने के लिए स्थानांतरित करते हैं और प्रीप्रोसेसर निर्देशों को पूरी तरह से संकलित करते हैं जो पूरी फ़ाइल सामग्री को बहिष्कृत करते हैं। यह एक व्यापक रूप से इस्तेमाल किया दृष्टिकोण है।

0

आप लिनक्स कर्नेल में असेंबली परिभाषा के लिए ऐसा कुछ कर सकते हैं। प्रत्येक आर्किटेक्चर की अपनी निर्देशिका होती है (उदाहरण के लिए asm-x86)। ये सभी फ़ोल्डर्स एक ही उच्च स्तरीय हेडर फाइलों को उसी इंटरफेस को प्रस्तुत करते हैं। जब कर्नेल कॉन्फ़िगर किया जाता है, तो एएसएम नामक एक लिंक उपयुक्त एएसएम-आर्क निर्देशिका को लक्षित करता है। इस तरह, सभी सी फाइलों में फाइलें शामिल हैं।

1

एस 60 द्वितीय संस्करण और तृतीय संस्करण अनुप्रयोगों के बीच कई अंतर हैं जो कोड तक सीमित नहीं हैं: एप्लिकेशन संसाधन फाइलें अलग-अलग हैं, ग्राफ़िक प्रारूप और उन्हें पैक करने के लिए टूल अलग-अलग हैं, mmp-files कई तरीकों से भिन्न होती है।

मेरे अनुभव के आधार पर, इसे स्वचालित करने की कोशिश न करें, लेकिन दूसरे संस्करण और तृतीय संस्करण के लिए अलग-अलग बिल्ड स्क्रिप्ट करें। कोड स्तर में, सामान्य सार तत्वों वाले वर्गों के लिए अलग मतभेद, केवल दुर्लभ मामलों में झंडे का उपयोग करते हैं।

+0

+1। कुछ पुनरावृत्ति से बचने के लिए हम पाइथन के साथ बिल्ड स्क्रिप्ट को स्वतः उत्पन्न करते थे। मूल रूप से प्रतिस्थापन और सशर्तों में से अधिकांश ने किया - इन दिनों शायद डीजेगो टेम्पलेट्स एक कोशिश के लायक होंगे। बेशक बिल्ड चेन उन्हें मेकफ़ाइल में पर्ल के साथ संसाधित करेगा। मुझे विश्वास है कि अंत में एक कंपाइलर शामिल है ;-) –

0

आपको कोड के माध्यम से #ifs फैलाने का प्रयास करना चाहिए।

इसके बजाय; वैकल्पिक मैक्रोज़ को परिभाषित करने के लिए शीर्षलेख फ़ाइलों में #if का उपयोग करें और फिर कोड में एकल मैक्रो का उपयोग करें।

यह विधि आपको कोड को और अधिक पढ़ने योग्य रखने की अनुमति देती है।

उदाहरण:

Plop.h 
====== 

#if V1 
#define MAKE_CALL(X,Y) makeCallV1(X,Y) 
#elif V2 
#define MAKE_CALL(X,Y) makeCallV2("Plop",X,222,Y) 
.... 
#endif 


Plop.cpp 
======== 

if (pushPlop) 
{ 
    MAKE_CALL(911,"Help"); 
} 

अपने स्वयं के कार्यों में इस विभाजन संस्करण विशिष्ट कोड सुविधाजनक बनाने में मदद करने के लिए, तो मैक्रो का उपयोग के रूप में ऊपर दिखाए गए कार्यों सक्रिय करने। इसके अलावा आप एक सतत इंटरफेस को आजमाने और प्रदान करने के लिए एसडीके के बदलते हिस्सों को अपनी कक्षा में लपेट सकते हैं, तो आपके सभी मतभेद रैपर वर्ग के भीतर प्रबंधित किए जाते हैं जो आपके कोड को छोड़कर काम को और अधिक साफ करता है।

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