2013-09-23 3 views
1

Учитывая следующий код,Multiple определение маркера

button.h

#ifndef BUTTON_H_ 
#define BUTTON_H_ 

#define true 1 
#define false 0 

#include <avr/io.h> 
#include <avr/interrupt.h> 
#include <timer0.h> 

typedef struct { 
    unsigned char port; 
    unsigned char pin; 
    unsigned long timestamp; 
} BUTTONS; 

BUTTONS button_1; 
BUTTONS button_2; 
BUTTONS button_3; 

enum BUTTONS_ID{BUTTONS_ID_1,BUTTONS_ID_2,BUTTONS_ID_3,BUTTONS_ID_COUNT}; 

BUTTONS* button[BUTTONS_ID_COUNT] = {&button_1,&button_2,&button_3}; 

void Button_init(void); 
#endif //BUTTON_H_ 

и button.c

#include <button.h> 

enum BUTTONS_state{BUTTON_STATE_UNPRESSED,BUTTON_STATE_DEBOUNCING,BUTTON_STATE_PRESSED}; 
int state = BUTTON_STATE_UNPRESSED; 

void Button_init(void){ 

    button[BUTTONS_ID_1]->port = PINB; 
    button[BUTTONS_ID_1]->pin = PINB4; 
    button[BUTTONS_ID_1]->timestamp = 0; 
} 

Я получаю следующее сообщение об ошибке: button.cpp: несколько определений из `button_1' . Я знаю, что я должен что-то делать неправильно. Я совершенно новый при использовании структуры, ошибка должна исходить оттуда. В принципе, я хотел создать переменную кнопки, которую я мог бы получить из своей основной программы, если это необходимо. Есть ли способ определить их в моем .h и инициализировать их внутри моего .c, а затем получить к ним доступ из моего основного файла?

Спасибо

+1

Расширение файла 'cpp' означает, что вы компилируете компилятор C++, а не C. Поэтому ваш вопрос действительно о C++. –

ответ

1

Вы определили button1 и несколько других объектов в файле заголовка. Если вы включите этот заголовок в несколько единиц перевода (прочитайте: исходные файлы), вы получите одно определение для каждой единицы перевода, которую вы компилируете. Затем, когда вы попытаетесь связать -> KABOOM.

Простым решением является «не помещать код, который определяет объекты в вашем заголовке». Если вам нужно получить к ним доступ в нескольких исходных файлах, вы можете оставить декларации, но вам нужно будет пометить их extern. Затем вы можете сделать определение в исходном файле в другом месте.

+0

Для примера я хотел бы объявить 'Экстерн КНОПКИ * Кнопка [BUTTONS_ID_COUNT]' в моей .h и в моем другом файле писать 'кнопку [BUTTONS_ID_COUNT] = {& button_1, & button_2, & button_3};' Правильно ли это? –

+0

Да, но вам также нужно сделать то же самое для кнопок 'button1',' button2' и 'button3'. –

0

Вы не должны объявлять переменные в файлах заголовков. Это связано с тем, что когда заголовочный файл # включен в файл c, он буквально копируется на него препроцессором.

Так что, если 2 файла c содержат один и тот же файл h, который, в свою очередь, объявляет переменную, вы получаете одну и ту же переменную, объявленную дважды в обоих файлах. Вероятно, это произошло здесь - вы, вероятно, # включили button.h в другой c-файл.

Лучший способ сделать переменное приложение глобальным - объявить его только в одном файле, а затем объявить его с помощью extern в каждом файле c, где вы хотите его использовать.

В вашем примере, сделать

BUTTONS button_1; 
BUTTONS button_2; 
BUTTONS button_3; 

в одном гр файл, а во всех остальных гр файлов, где вы хотите использовать эти переменные, сделать:

extern BUTTONS button_1; 
extern BUTTONS button_2; 
extern BUTTONS button_3; 

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

Кроме того, лучше попытаться не использовать глобальные переменные приложения, что приводит к способам модульного программирования, низкой связи и всего этого. Это очень интересная и важная тема, но для широкого ответа. :-)

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