2009-03-07 14 views
19

मैं एक हेडर फाइल port.h, port.c है, और मेरी main.cअपरिभाषित सी struct आगे घोषणा

मैं निम्नलिखित त्रुटि मिलती है सोचा क्योंकि मैंने अपनी .h फ़ाइल में संरचना घोषित की है और .c फ़ाइल में वास्तविक संरचना ठीक है।

मुझे आगे की घोषणा करने की आवश्यकता है क्योंकि मैं अपने port.c फ़ाइल में कुछ डेटा छिपाना चाहता हूं।

मेरी port.h में मैं निम्नलिखित है:

/* port.h */ 
struct port_t; 

port.c:

/* port.c */ 
#include "port.h" 
struct port_t 
{ 
    unsigned int port_id; 
    char name; 
}; 

main.c:

/* main.c */ 
#include <stdio.h> 
#include "port.h" 

int main(void) 
{ 
struct port_t ports; 

return 0; 
} 

किसी भी सुझाव के लिए बहुत धन्यवाद,

+0

संकलक जीसीसी C99 – ant2009

+9

ध्यान दें कि एक चरित्र बंदरगाह नाम बहुत ही रोमांचक होने के लिए नहीं जा रहे हैं: आप port.h में विशेष malloc (और) रैपर बनाने के लिए रूप में अच्छी तरह की आवश्यकता होगी! –

उत्तर

24

दुर्भाग्य से, कंपाइलर की ज़रूरत है main.c संकलित करते समय port_t (बाइट्स में) के आकार को जानने के लिए, इसलिए आपको हेडर फ़ाइल में पूर्ण प्रकार की परिभाषा की आवश्यकता है।

+0

स्पष्ट रूप से आप सही हैं। सी सी ++ से काफी अलग तरीके से संभालने लगते हैं। –

+5

@ लिटब: आपका क्या मतलब है? मैं C++ में विश्वास करता हूं, मुख्य बंदरगाह को "बंदरगाह" उदाहरण बनाने के लिए अभी भी port_t की पूर्ण परिभाषा की आवश्यकता होगी। –

+1

@ मैथ्यू: यह स्पष्ट करने योग्य हो सकता है कि यह पूर्ण _type_ defintion है जिसे हेडर फ़ाइल में होना आवश्यक है; परिवर्तनीय परिभाषा स्रोत फ़ाइल में जाती है। –

15

आप port_t संरचना के आंतरिक डेटा को छिपाने के लिए आप की तरह कैसे मानक पुस्तकालय FILE वस्तुओं संभालती है एक तकनीक का उपयोग कर सकते हैं। ग्राहक कोड केवल FILE* आइटमों से संबंधित है, इसलिए उन्हें FILE संरचना में वास्तव में क्या है इसकी कोई आवश्यकता नहीं है (वास्तव में, आमतौर पर नहीं कर सकते)। इस विधि में कमी यह है कि क्लाइंट कोड केवल उस प्रकार के चर को घोषित नहीं कर सकता है - वे केवल इसके लिए पॉइंटर्स ही हो सकते हैं, इसलिए ऑब्जेक्ट को कुछ एपीआई का उपयोग करके बनाया और नष्ट किया जाना चाहिए, और सभी उपयोग ऑब्जेक्ट कुछ एपीआई के माध्यम से होना चाहिए।

लाभ यह करने के लिए आप कैसे port_t वस्तुओं इस्तेमाल किया जाना चाहिए के लिए एक अच्छा स्वच्छ इंटरफ़ेस है कि है, और आप निजी बातें निजी (गैर-निजी बातें उन तक पहुँचने के लिए ग्राहक के लिए गेटर/सेटर कार्यों की जरूरत है) रखने देता है।

बस लाइब्रेरी में FILE I/O को कैसे प्रबंधित किया जाता है।

/* port.h */ 
#ifndef _PORT_H 
#define _PORT_H 
typedef struct /* Define the struct in the header */ 
{ 
    unsigned int port_id; 
    char name; 
}port_t; 
void store_port_t(port_t);/*Prototype*/ 
#endif 

/* port.c */ 
#include "port.h" 
static port_t my_hidden_port; /* Here you can hide whatever you want */ 
void store_port_t(port_t hide_this) 
{ 
    my_hidden_port = hide_this; 
} 

/* main.c */ 
#include <stdio.h> 
#include "port.h" 
int main(void) 
{ 
    struct port_t ports; 
    /* Hide the data with next function*/ 
    store_port_t(ports); 
    return 0; 
} 

यह एक हेडर फाइल में चर निर्धारित करने आम तौर पर अच्छा नहीं है:

+0

यहां तक ​​कि FILE संरचना स्पष्ट रूप से stdio.h में रखी गई है। कम से कम, मेरे सिस्टम पर। "टाइपपीफ स्ट्रक्चर __sFILE {...} फ़ाइल;" फाइल पॉइंटर्स के माध्यम से हमें कभी भी अपने आंतरिक (जो बहुत रोचक होते हैं - पढ़ने/लिखने/आदि के लिए फ़ंक्शन पॉइंटर्स) को देखने की आवश्यकता नहीं होती है, लेकिन वे अभी भी वहां हैं। –

+0

यह भी ध्यान दें: FILE * पॉइंटर्स से निपटने के लिए और संरचना FILE * पॉइंटर्स नहीं, आपको "typedef" संस्करण का उपयोग करने की आवश्यकता है। उपरोक्त कोड को "struct port_t" की आवश्यकता है। यदि यह "typedef struct port_t {...} पोर्ट" था तो यह FILE * पॉइंटर्स के समान पोर्ट * सूचक का उपयोग कर सकता था। –

+0

@ क्रिस, इसे पूरी तरह से घोषित नहीं किया जाना चाहिए, एक कार्यान्वयन तकनीकी रूप से एक फ़ाइल संरचना को चार [X] के रूप में परिभाषित कर सकता है क्योंकि मानक में कुछ भी नहीं है जो संरचना को निर्धारित करता है - इसलिए यह छिपाया जा सकता है। – paxdiablo

0

मैं एक अलग तरह की सिफारिश करेंगे।

+1

वह एक शीर्षलेख में एक चर परिभाषित नहीं कर रहा था, वह port_t प्रकार घोषित करने की कोशिश कर रहा था। –

+0

वह get/set या simulair फ़ंक्शंस का उपयोग क्यों नहीं कर रहा है मुझे मारता है ... लेकिन हाँ आप सही हैं ... मैं सिर्फ एक सुझाव दे रहा था ... – eaanon01

6

एक आम समाधान है कि मैं का उपयोग करें:

/* port.h */ 
typedef struct port_t *port_p; 

/* port.c */ 
#include "port.h" 
struct port_t 
{ 
    unsigned int port_id; 
    char name; 
}; 

आप समारोह इंटरफेस में port_p का उपयोग करें।

port_p portAlloc(/*perhaps some initialisation args */); 
portFree(port_p); 
संबंधित मुद्दे