मेरे पास एक सी प्रोजेक्ट है जिसे विभिन्न (पीसी और एम्बेडेड) प्लेटफॉर्म पर पोर्टेबल बनाने के लिए डिज़ाइन किया गया है।मैं सामान्य हेडर में कार्यान्वयन-परिभाषित संरचना को कैसे टाइप करूं?
एप्लिकेशन कोड विभिन्न कॉल का उपयोग करेगा जिसमें प्लेटफ़ॉर्म-विशिष्ट कार्यान्वयन होंगे, लेकिन पोर्टेबिलिटी में सहायता के लिए एक सामान्य (सामान्य) API साझा करें। मैं फ़ंक्शन प्रोटोटाइप और संरचनाओं को घोषित करने के सबसे उचित तरीके से निपटने की कोशिश कर रहा हूं।
यहाँ क्या मैं अब तक लेकर आए हैं:
main.c:
#include "generic.h"
int main (int argc, char *argv[]) {
int ret;
gen_t *data;
ret = foo(data);
...
}
generic.h: (मंच-नास्तिक शामिल)
typedef struct impl_t gen_t;
int foo (gen_t *data);
impl.h: (प्लेटफ़ॉर्म-विशिष्ट घोषणा)
#include "generic.h"
typedef struct impl_t {
/* ... */
} gen_t;
impl.c: (प्लेटफ़ॉर्म-विशिष्ट कार्यान्वयन)
int foo (gen_t *data) {
...
}
बिल्ड:
gcc -c -fPIC -o platform.o impl.c
gcc -o app main.c platform.o
अब, यह काम करने के लिए ... में है कि यह संकलित प्रकट होता है ठीक। हालांकि, मैं आमतौर पर अपने संरचनाओं को टैग नहीं करता क्योंकि उन्हें typedef
'डी उपनाम के बाहर कभी भी एक्सेस नहीं किया जाता है। यह एक छोटा सा नाइट-पिक है, लेकिन मुझे आश्चर्य है कि अज्ञात structs के साथ एक ही प्रभाव प्राप्त करने का कोई तरीका है?
मैं भी भावी पीढ़ी के लिए पूछ रहा हूँ, के बाद से मैं थोड़ी देर के लिए खोज की है और निकटतम जवाब मैंने पाया यह था: (Link)
मेरे मामले में, यह सही तरीका नहीं हो सकता है, आवेदन के रूप में विशेष रूप से कभी भी कार्यान्वयन शीर्षलेखों को सीधे शामिल नहीं करना चाहिए - संपूर्ण बिंदु प्लेटफ़ॉर्म से प्रोग्राम को डीक्यूपल करना है।
मैं दूसरे से कम आदर्श तरीके के एक जोड़े इसका समाधान करने के देखते हैं, उदाहरण के लिए:
generic.h:
#ifdef PLATFORM_X
#include "platform_x/impl.h"
#endif
/* or */
int foo (struct impl_t *data);
न तो इनमें से
विशेष रूप से आकर्षक लगता है, और निश्चित रूप से नहीं मेरी शैली। जबकि मैं अपस्ट्रीम तैरना नहीं चाहता हूं, मैं भी विरोधाभासी शैली नहीं चाहता हूं जब मेरे मन में ठीक से लागू करने के लिए एक अच्छा तरीका हो सकता है। तो मुझे लगता है कि टाइपपीफ समाधान सही रास्ते पर है, और यह केवल स्ट्रक्चर टैग बैगेज है जिसके साथ मुझे छोड़ा गया है।
विचार?
आप केवल 'gen_t' को पॉइंटर प्रकार (एक हैंडल) बना सकते हैं। फिर ग्राहकों को इसे शुरू/उपयोग/नष्ट करने के लिए अपने एपीआई का उपयोग करना होगा। या थोड़ी भिन्नता, अपनी सार्वजनिक रूप से उजागर संरचना में वास्तविक कार्यान्वयन के लिए एक अपारदर्शी सूचक शामिल है। अन्यथा, आप और कुछ नहीं कर सकते हैं। एक ऑब्जेक्ट या जिस तरह से ट्रैक किया जाना चाहिए उसे क्लाइंट को जानना होगा। –
इसमें कोई समस्या है कि generic.h को impl.h.h से पहले शामिल किया जा रहा है। लेकिन, generic.h impl.h.E. में परिभाषित संरचना का संदर्भ दे रहा है। एक आगे संदर्भ। (संभवतः संकलित नहीं होगा) जेनेरिक में बहुत बेहतर है। impl.h शामिल करें (जहां impl.h प्लेटफॉर्म विशिष्ट है) तो जेनेरिक.h इसका उपयोग करने का प्रयास करते समय संरचना पहले ही परिभाषित की जाएगी। – user3629249
संरचना के रूप में परिभाषित करना कहीं बेहतर है: struct tagname {;;; }; फिर हमेशा इसे 'struct tagname myname' के रूप में संदर्भित करें; इसके लिए कई कारण हैं: 1) नामित structs एक अवमूल्यन प्रारूप है 2) डिबगर्स टैग फ़ील्ड का संदर्भ फ़ील्ड का उपयोग करते हैं, आदि 3) एक स्ट्रक्चर पर टाइपपीफ का उपयोग करना (सामान्य रूप से) खराब प्रोग्रामिंग अभ्यास – user3629249