2016-02-23 4 views
1

У меня есть определение fifo_t в моем fifo.c файл, как показано ниже. Что должно быть объявлением этого типа в файле заголовка fifo.h? Я хочу, чтобы содержимое этой структуры было известно только в файле fifo.c. Кроме того, я не хочу, чтобы создать экземпляр этой структуры через struct struct_name var;. Только действительный путь должен быть fifo_t var;Объявить структуру в заголовочном файле

typedef struct { 
    uint8_t *buffer, 
    uint8_t indexRead, 
    uint8_t indexWrite, 
    uint8_t used, 
    uint8_t size 
} fifo_t; 
+0

Вы не можете сделать это с сыром 'структуры сам. Вы можете сделать 'typedef' для непрозрачного _pointer_ в' struct'? Это приемлемо? Вы не можете фактически объявить 'fifo_t var;' в другом коде без полного определения структуры, потому что у другого кода не будет информации, чтобы выделить достаточно памяти для ее хранения. – ShadowRanger

+2

Если вы хотите, чтобы структура была известна только в определенном исходном файле, почему бы просто не определить ее в исходном файле вместо файла заголовка? –

+2

Необязательно, если вам нужна структура только в нескольких исходных файлах, но не в большинстве из них, затем создайте новый «закрытый» заголовок (например, «fifo_private.h') файл, содержащий эту структуру. –

ответ

0

вы не можете скрыть содержимое fifo_t, если вы хотите, чтобы иметь возможность создать его в стек, как fifo_t var;, потому что sizeof(fifo_t) неизвестно

Вы можете сделать FORVARD декларацию fifo_t в заголовке: struct fifo_t;. В других файлов, которые вы будете иметь возможность создавать poiners для fifo_t и работать с ними, используя функции, которые должны быть реализованы в & fifo.c

fifo_t *var; 
create(&var); 
do_work(var); 
destroy(var); 
4

Если вы хотите, чтобы только быть в состоянии передавать указатели на fifo_t вокруг, то вы можете только переслать-объявить его в файл заголовка. Однако typedef для неназванных структур действует только при определении содержимого структуры. Поэтому, если вы не хотите компилировать struct fifo_t var;, вам придётся использовать какое-то контр-интуитивное имя, может быть, что-то вроде fifo_t_. Например:

typedef struct fifo_t_ fifo_t; 
void fifo_use(fifo_t*); // ok, just uses pointer 

А затем в файле .c, делать (и, пожалуйста, обратите внимание, что при использовании запятой для отдельных членов не является допустимым синтаксисом):

struct fifo_t_ { 
    uint8_t *buffer; 
    uint8_t indexRead; 
    uint8_t indexWrite; 
    uint8_t used; 
    uint8_t size; 
}; 

void fifo_use(fifo_t* f) { 
    f->indexRead = 1; 
} 

Кроме того, обратите внимание, что fifo_t var; не будет потому что вам нужно знать размер структуры, чтобы выделить место для нее. То, что вы могли сделать, это использовать указатели внутри, таким образом, прозрачно для пользователя:

// in .h file: 

typedef struct fifo_t_* fifo_t; 

void fifo_init(fifo_t*); 
void fifo_free(fifo_t); 
void fifo_use(fifo_t); 

// in .c file: 

struct fifo_t_{ 
    uint8_t *buffer; 
    uint8_t indexRead; 
    uint8_t indexWrite; 
    uint8_t used; 
    uint8_t size; 
}; 

void fifo_init(fifo_t* f) { 
    *f = (fifo_t)malloc(sizeof(struct fifo_t_)); 
} 

void fifo_free(fifo_t f) { 
    free(f); 
} 

void fifo_use(fifo_t f) { 
    f->indexRead = 1; 
} 


// somewhere else 

int main() { 
    fifo_t fifo; 
    fifo_init(&fifo); 
    fifo_use(fifo); 
    fifo_free(fifo); 
} 
+0

Возможно, лучше иметь 'typedef void * fifo_t;' вместо абзаца 'struct' pointer. – LPs

+0

@LPs Проблема в том, что тогда вы можете передать что угодно, и вы потеряете некоторую степень безопасности типов. –

+0

Нет необходимости в нижнем подчеркивании имени структуры, названия структур в отдельном пространстве имен вместе с объединениями. Так, например, 'typedef struct fifo_t fifo_t;' будет работать нормально. Я также советовал бы объявить псевдоним типа в качестве указателя. Если нужен указатель, то лучше сделать его явным (используется способ 'FILE *'), будет легче запомнить, является ли переменная указателем, если она явно объявлена ​​как указатель. –

0

Если вы хотите, чтобы сделать определение структуры в fifo.h это путь :

fifo.h

... 
#ifdef FIFO 
typedef struct { 
    uint8_t *buffer, 
    uint8_t indexRead, 
    uint8_t indexWrite, 
    uint8_t used, 
    uint8_t size 
} fifo_t; 
#else 
... 
#endif 
... 

fifo.c

#define FIFO 
#include "fifo.h" 
... 

так fifo.h все еще может быть включать в других исходных файлах, но тип структуры является скрыть, это видно только с fifo.c

Смежные вопросы