#ifndef не работает должным образом - PullRequest
2 голосов
/ 01 декабря 2011

Получение LNK2005, "уже определенного в GUI.obj" для указателя функции в PAL.h

//GUI.cpp
#include "PAL.h"

//PAL.h
#define PAL_INCLUDE
int (*addPAL)( int, void(*)(), void(*)() );

//main.cpp
#include "GUI.h"
#ifndef PAL_INCLUDE
#include "PAL.h"
#endif

Я неправильно понял природу включений и #ifndef?

Ответы [ 4 ]

5 голосов
/ 01 декабря 2011

Вы получаете ошибку, вероятно, потому что препроцессор обрабатывает main.cpp перед GUI.cpp.Попробуйте изменить содержимое вашего PAL.h на следующее:

 #ifndef PAL_INCLUDED
 #define PAL_INCLUDED
 // definitions
 #endif

Ссылка

Включить охрану

3 голосов
/ 01 декабря 2011

Я думаю, вы должны использовать include guard over PAL.h.

Если я понимаю, что вы пытаетесь сделать, этот код будет гораздо более понятным (и довольно распространенным):

GUI.h

#ifndef _GUI_H_
#define _GUI_H_
...
#endif

GUI.cpp

#include "PAL.h"
...

PAL.h

#ifndef _PAL_H_
#define _PAL_H_

int (*addPAL)( int, void(*)(), void(*)() );

#endif

main.cpp

#include "GUI.h"
#include "PAL.h"
...

Надеюсь, это поможет.

2 голосов
/ 01 декабря 2011

addPal определяется дважды, один раз в GUI.cpp и один раз в main.cpp.То, что вы хотите, это определить его один раз и объявить его везде, где вам нужно его использовать.Я предлагаю поместить

int (*addPAL)( int, void(*)(), void(*)() );

в один из файлов .cpp (я не видел достаточно кода, чтобы решить, к какому из них он принадлежит), затем объявление:файл заголовка.Extern сообщает компилятору, что указатель addPAL существует, но определен в другом месте

1 голос
/ 01 декабря 2011

Main.cpp и GUI.cpp скомпилированы отдельно друг от друга и затем связаны друг с другом. Это означает, что состояние препроцессора сбрасывается между двумя компиляциями, и вы теряете определение PAL_INCLUDE
Защитники заголовков предотвращают включение заголовка более одного раза другими заголовками в одном и том же модуле компиляции, чтобы не допустить столкновения в компоновщике.

Попробуйте поставить static перед объявлением метода - это ограничивает функцию текущим модулем, предотвращая эту проблему. Для получения дополнительной информации см. Что такое «статическая» функция?

...