2017-02-15 6 views
4

На языке C предположим, что я определяю struct s, внутри файла f.c. Я не хочу, чтобы этот struct был доступен другим людям, поэтому я не помещаю его в f.h. В моем проекте у меня есть много других файлов, включая g.c, который хочет получить доступ к struct s в f.c.Сделать структуру не в заголовке доступной для других файлов

Есть ли способ сделать это возможным? Я думаю, что s должен быть глобальной переменной extern, объявленной в g.h. Они свяжутся во время компиляции. Я не уверен, возможно ли это или правильный/лучший способ сделать что-то подобное.

+0

A Тип должен быть доступен до его использования. Вы либо используете заголовок, либо копируете вставить определение структуры. Невозможно разделить типы между единицами перевода. – DeiDei

+1

Вам необходимо создать API в 'f.c', которые создают и изменяют эту структуру. Вы передаете 'void *' обратно вызывающему, чтобы он не мог получить доступ к своим полям. –

+3

Определить *, доступный другим людям *. – rustyx

ответ

4

Вы можете добавить в свой заголовочный файл декларацию перед этим типом и ее можно рассматривать как непрозрачный (неполный) тип.

struct s; 

Другие люди могут обратиться к struct s *, но они не могут использовать struct s, поскольку тип является неполным им.

Если вы предоставляете API-интерфейсы, они могут вызывать API-интерфейсы для создания, изменения и уничтожения экземпляров struct s.

enum struct_s_field { 
    S_FIELD_NAME, 
    S_FIELD_VALUE, 
    /* ... */ 
}; 

struct s * make_s(); 
void unmake_s(struct s *); 
void update_s(struct s *, enum struct_s_field, ...); 
1

Один из способов сделать это состоит в создании интерфейсов API в f.c, инициализирующих, читать и писать struct s структуры. Чтобы скрыть содержимое этой структуры от вызывающего, вы возвращаете void * обратно вызывающему абоненту, который он использует при последующих вызовах API f.c.

Например: определение

void *pS; 

pS = sInit(); 

void *sInit(void) 
{ 
    return malloc(sizeof(struct s)); 
} 
+0

@Downvoter: что случилось с возвращаемым указателем 'void *'? – d3L

+2

@ d3l 'void *' - это отверстие в системе типов. Любой объект-указатель в C конвертируется в и из 'void *' неявно без необходимости каких-либо бросков. Зачем делать такую ​​дыру, когда вы можете использовать указатели для объявленных, но не определенных структур, как в ответе @ jxh? – PSkocik

+0

Да, хорошо, это хороший момент. – d3L