Я унаследовал некоторый код *, который объявляет и определяет структуру в заголовочном файле (a_A.h).Эта структура находится в верхнем файле дерева иерархии включений, которое символически выглядит следующим образом:
file: t_T.h (#includes "c_C.h") //defines a struct
file: c_C.h (#includes "h_H.h")
file: h_H.h (#includes "a_C.h")
file: a_C.h (#includes <stdio.h>)
Каждый заголовок имеет соответствующие средства защиты заголовков и выглядит нерекурсивным, если рассматривать его как плоскую коллекцию файлов.Однако файлы c_C.h и a_C.h находятся в одной библиотеке.В то время как h_H.h находится в другой библиотеке.С точки зрения библиотеки это символически выглядит как:
t_T.h (includes a file from Lib_C)
Lib_C: (includes a file from Lib_H)
Lib_H (includes a file from Lib_C)
, который является рекурсивным и является вероятной причиной проблем с переопределением, когда я компилирую код (компоновщик жалуется, что структура в файле a_C.h переопределена).
1) Правильно ли я идентифицировал проблему?
2) Если да, то почему?Я предполагаю, что связанные объекты в библиотеке выглядят плоскими для компоновщика (то есть они потеряли свой контекст иерархии).И если угадать несколько правильно, то:
3) Должен ли я считать, что защита заголовков ограничена областью их соответствующей библиотеки?
Ниже приведено сообщение об ошибке из окна проблем:
symbol "ov5642_1280x960_RAW" redefined: first defined in "./TakePhoto.obj"; redefined in "./ArduCam/ov5642_Config.obj"
Заголовок в ./TakePhoto:
#ifndef TAKEPHOTO_H
#define TAKEPHOTO_H
#include "ov5642_Config.h"
#include "HAL_ArduCAM.h"
...
#endif /* TAKEPHOTO_H_ */
Заголовок в ./ArduCAM/ov5642_Config.h:
#ifndef ARDUCAM_OV5642_CONFIG_H_
#define ARDUCAM_OV5642_CONFIG_H_
#include "HAL_ArduCAM.h"
#include "ov5642_Sensor_Values.h"
....
#endif /* ARDUCAM_OV5642_CONFIG_H_ */
Заголовок в HAL_ArduCAM
#ifndef HAL_ArduCAM_h
#define HAL_ArduCAM_h
#include <stdint.h>
#include "driverlib.h"
....
#endif /* HAL_ArduCAM_h */
ov5642_Sensor_Values.h имеет следующий
#ifndef ARDUCAM_OV5642_SENSOR_VALUES_H_
#define ARDUCAM_OV5642_SENSOR_VALUES_H_
#include <stdint.h>
const struct sensor_reg ov5642_1280x960_RAW[] =
{
{0x3103,0x93},
{0x3008,0x02},
{0x3017,0x7f},
.....
#endif /* ARDUCAM_OV5642_SENSOR_VALUES_H_ */
Кажется, что содержимое OV5642_Sensor_Values копируется дважды, один раз для TakePhotoи еще раз для ovV5642_Config, несмотря на их охрану заголовка.Первоначально я думал, что существует рекурсивная зависимость, но не нашел ее.
Хорошо, я сделал пример, вставленный ниже.В этом примере пять файлов, три файла (bar.h, foo.h, foo.c находятся в библиотеке), остальные два файла (foo1.h, foo1.c) - нет.Обратите внимание, что foo.h включает в себя bar.h, а foo1 включает как foo.h, так и bar.h.
Я предполагаю, что защитные заголовки bar.h не сохраняются, когда препроцессор копирует в foo.h.Таким образом, когда foo1 включает bar.h и foo.h, возникает переопределение символа.Поэтому, чтобы ответить на мой собственный вопрос, нет, это не проблема библиотеки.Несохранение жатки кажется вероятной причиной моей проблемы.
Они наклеены ниже.
/*
* bar.h
*
*/
#ifndef ARDUCAM_BAR_H_
#define ARDUCAM_BAR_H_
#include <stdint.h>
typedef struct regStruct {
uint16_t reg;
uint8_t val;
} regStruct;
const struct regStruct regArray[] =
{
{0x3103,0x03},
{0x3104,0x03},
{0x3008,0x82},
{0xffff,0xff},
};
const struct regStruct tinyArray[] =
{
{0x3106,0x03},
{0x3003,0x82},
{0xffff,0xff},
};
#endif /* ARDUCAM_BAR_H_ */
/*
* foo.h
*
*
*/
#ifndef ARDUCAM_FOO_H_
#define ARDUCAM_FOO_H_
#include <stdint.h>
#include <stdio.h>
#include "bar.h" //including this file causes redefinition
typedef struct Init_Parameters {
//! Select sensor resolution
//! options.
//! \n Valid values are:
//! - \b big
//! - \b small
//! - \b tiny
uint8_t size;
} Init_Parameters;
uint8_t Sensor_Init(Init_Parameters *param);
typedef enum {
small=0,
big,
tiny
} select_size;
#endif /* ARDUCAM_FOO_H_ */
/*
* foo.c
*
*
*/
#include "foo.h"
uint8_t Sensor_Init(Init_Parameters *param)
{
switch(param->size)
{
case big:
break;
case small:
break;
case tiny:
break;
}
return 0x01;
}
/*
* foo1.h
*
* Created on: Feb 28, 2019
* Author: jnadi
*/
#ifndef FOO1_H_
#define FOO1_H_
#include "foo.h"
#include "bar.h"
#endif /* FOO1_H_ */
/*
* foo1.c
*
* Created on: Feb 28, 2019
* Author: jnadi
*/
#include "foo1.h"
void Camera_Init(){
Init_Parameters setParams; //create instance
setParams.size=big;
Sensor_Init(&setParams);
}