2013-10-11 8 views
1

Мне нужно определить структуру в исходном файле, а также другие источники должны уметь это видеть. Заявляю структуру в одном исходном файле, а затем экстерн декларации в заголовке включить в других источниках, но компилятор следующих ошибок есть:объявить структуру в заголовке и использовать в нескольких источниках

lcd.c(24): error: #147: declaration is incompatible with "struct graph_obj arrow_right" (declared at line 45 of "lcd.h") 

.C файл

struct graph_obj 
{ 
    const u16 *id; 
    int x,y; 
    u16 w, h; 
}; 

u32 lcdid; 

struct graph_obj btn0; 
struct graph_obj btn1; 
struct graph_obj btn2; 
struct graph_obj btn3; 

, а затем .h файл

extern struct graph_obj 
{ 
    const u16 *id; 
    int x,y; 
    u16 w, h; 
}; 

extern u32 lcdid; 

extern struct graph_obj btn0; 
extern struct graph_obj btn1; 
extern struct graph_obj btn2; 
extern struct graph_obj btn3; 

Итак, что мне делать?

+4

можете ли вы отправить код? судя по тому, что вы пишете, вы делаете то, что нужно. – wirm

+0

Что вы должны сделать, так это показать фактический код/​​строку с ошибкой в ​​'lcd.c' и соответствующее объявление в файле заголовка. – crashmstr

+0

только что добавленные коды, tnx – Beh

ответ

2
in header: 

typedef struct 
{ 
    const u16 *id; 
    int x,y; 
    u16 w, h; 
}GRAPH_OBJ; 


extern GRAPH_OBJ graph_obj, *pGraph_obj; 

В C модулей:

GRAPH_OBJ graph_obj, *pGraph_obj; 

Подобный код, за исключением того, что здесь, вы создали новый тип (GRAPH_OBJ), и он будет вести себя как любой тип, который extern'd. И вам не нужно полностью воссоздавать определение структуры, все это содержится в GRAPH_OBJ. Кстати, Here - хорошее сообщение о том, как правильно использовать внешние символы.

+0

Добро пожаловать. Кстати, я не дал еще одного преимущества (хотя это ясно сказано в ссылке), что из-за использования модификатора extern таким образом структуры, созданные таким образом, имеют видимость проекта, то есть члены присваивают значения в одном модуле .c , будет одинаковым значением в любом другом модуле, где используется эта структура. Это может быть хорошо, но если это не так, это меч с двойным острием. – ryyker

+0

хорошая точка, tnx. поэтому позвольте мне задать еще один вопрос. не использует выражение extern, вообще снижает производительность выполнения? – Beh

+0

Я не думаю, что _using_, или _not using_ 'extern' приведет к изменению производительности _execution_, но это приведет к изменению поведения вашей программы. т.е. используя extern в том, как он используется выше, вы не только получаете переменную 'GRAPH_OBJ' (вашу структуру), доступную для использования в каждом модуле .c, вы также позволяете сразу же отображать значения, назначенные ее членам в каждом модуле .c, который использует эту структуру (как я уже говорил). Но нет.Я не вижу никаких причин для ухудшения производительности с помощью 'extern'. – ryyker

2

Вам необходимо объявить и определить структуру в файле заголовка, а затем включить этот заголовок в соответствующий источник. наличие заголовка со всеми определениями прототипов и общественных структур, включенными в источник, является хорошей идеей и широко применяемой практикой. Как было предложено в другом ответе, «защитники заголовков» должны быть.

EDIT: Вы определили структуру 2 раза, то есть где ошибка. extern действует только для переменных, а не для прототипов.

+0

что я должен делать вместо этого? – Beh

+0

@Beh, вы должны объявить и определить все прототипы (публичные структуры, форвардное объявление, макросы и т. Д.) В заголовке (lcd.h в вашем случае). Не забудьте включить охранников в заголовки, они ваши друзья. Затем вы включаете lcd.h в lcd.c. Все общедоступные вещи уже находятся в lcd.h, и вы не должны объявлять их снова в lcd.c, поэтому вы помещаете в lcd.c только те вещи, которые являются «частными» для lcd.c (внутренние структуры, определения функций, внутренние макросы и т. д.). – wirm

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