- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我继承了一些代码*,它在头文件(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>)
每个 header 都有适当的 header 保护,并且当将其视为文件的平面集合时,它们似乎是非递归的。但是,文件 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) 我是否应该考虑将 header 防护限制在其各自库的范围内?
下面是问题窗口中的错误语句:
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 中的 header :
#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 中的 header
#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,尽管它们有 header 保护。我原本的想法是存在递归依赖但没有找到。
好的,我已经在下面粘贴了一个示例。此示例中有五个文件,其中三个文件(bar.h、foo.h、foo.c 驻留在库中),另外两个文件(foo1.h、foo1.c)不驻留在库中。请注意,foo.h 包含 bar.h,而 foo1 包含 foo.h 和 bar.h。
我推测当预处理器复制到 foo.h 时,bar.h 的保护 header 不会被保留。因此,当 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);
}
最佳答案
头文件的物理位置仅通过包含文件搜索路径影响 C 源代码编译。 header 必须位于搜索的目录之一中,如果有多个同名目录,则搜索路径顺序决定使用哪个目录。编译器不知道给定 header 和库之间的关联(如果有),并且不会影响编译,除非间接通过搜索路径。
您的主张
the linker complains that the struct in file a_C.h is redefined
(强调)仅当“结构”指的是结构类型的对象时才有意义。如果具有外部链接的变量在多个翻译单元中定义,则链接器可能会提示,如果 header 包含该变量的定义(而不是仅仅声明),则可能会发生这种情况。
如果问题是结构类型被重新定义,那么这将由编译器而不是链接器诊断,并且它往往会与您的结论相矛盾
Each header has the appropriate header guards
。适当的 header 保护正是可以防止此类类型重新定义问题的原因。
1) Did I correctly identify the issue?
当然,没有任何特殊性。与不同库关联的 header 之间存在双向 header 依赖关系,这反射(reflect)了设计不佳,但它本身不会导致编译或链接失败。
2) If so [...]
不适用
3) Should I consider header guards to be limited to the scope of their respective library?
没有。 header 保护仅在编译阶段相关,C 编译对库一无所知。编译器在翻译单个翻译单元的过程中处理的所有头文件都是平等的。事实上,这个区域的主要风险是相反的:头球护罩的碰撞。
<小时/>这回答了所提出的问题。至于您的构建问题的真实性质可能是什么,您没有向我们提供足够的信息,我们只能进行推测。上面已经表达了我自己的猜测。
关于c - header 防护是否仅限于各自库的范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54932620/
我的印象是 header guards 解决了重新定义的问题。我收到链接器错误,指出 .obj 文件中存在重新定义。这是我包含的 header ,问题在于所有全局声明的重新定义。 #ifndef DI
我正在 Microsoft Azure 中运行企业级应用程序。我想知道 Microsoft Azure 中 DDOS 投影的建议是什么。该文档明确指出该平台受到 DDOS 保护,但没有提供更多详细信息
我正在用 laravel sanctum 进行测试,但这里有一些问题.. 我正在创建管理员守卫。 当我将中间件更改为 auth:sanctum_admin .. 它应该只能由管理员访问,但在这里我可以
我有一个带有延迟加载模块的 Angular 4.3.6 应用程序。这是部分根路由器: const routes: Routes = [ { path: '', redirectTo: 'fleet
我有 Vaadin UI 的后端。我想保护后端数据库免受XSS攻击。对于 Vaadin UI 的 XSS 防护,您有何建议? 最佳答案 Vaadin 内置了 XSS 保护。所有组件都正确转义/编码 h
我正在尝试提高我的应用程序的安全性。每当我从用户(无论是通过 POST 还是 GET)接收到应该是整数的数据时,我都会适本地对其进行验证。但通常数据是 VARCHAR,有时可以包含 HTML。 在这种
我有一个具有此功能的服务,它会在 token 有效或无效时返回 true 或 false loggedIn() { return this.http.get('http://localhost:300
我们的应用程序中有几条路线,用户不应通过直接在浏览器的地址栏中输入网址来导航这些路线。 相反,当我们使用 router.navigate() 通过我们的应用程序逻辑以编程方式导航时,我们只想让它们可访
我通常在 .NET 中编写我的 SQL sql.Append("SELECT id, code, email FROM mytable WHERE variable = @variable "); 然
我需要同时将多行(1000 行)插入到 SQL Server 数据库中。我认为最好的方法是使用 SqlBulkCopy 但我不确定如何参数化插入查询以防止 SQL 注入(inject)。 你能帮我一下
Laravel 5.7 PHP 7.2.10 目前我可以使用 Web 和 api 防护中的任何一个,是否有任何方法可以同时允许两者,以便 Web 应用程序和 api 能够协同工作。 类似的东西 ret
Guard 总是因为这个问题而困扰我: .../gems/bundler-1.6.2/lib/bundler/runtime.rb:34:in `block in setup': You have a
我正在尝试通过 gmail api 从 Google 获取邮件 在收到 token 后对 Google_Client 进行身份验证时出现此错误 fatal error :未捕获异常“Google_Au
我是一名优秀的程序员,十分优秀!