我知道如何编写.h文件并包含防护程序。我想写一个包含全局变量的新bar123.h文件。假设bar123.c不存在。
其他头文件,例如bar.h将包括bar123.h,以使全局变量在需要它们的地方可见。
一个问题是,如果foo.c包括foo.h,该foo.h包括bar.h,该bar.h包括bar123.h,那么foo.c是否总是包含bar123.h?
另一个问题是,我应该如何修改Makefile和Kbuild文件?
我正在寻找一个简单的破解方案。
要回答您的第一个查询-Yes foo.c将始终包含bar123.h.
第二个查询,在Make文件中,您需要添加的唯一更改是在头包含文件的列表中添加这个bar123.h。既然你没有任何新的.o文件正在生成,你就不需要更改那个部分。
希望它能回答您的问题
全局变量必须存在于的某个位置,并且只能存在于的一个位置。这意味着它只需要在一个地方声明。
记住:H文件只是告诉编译器事物存在于的某个地方。C文件提供了这些东西的实际定义。
假设您的全球不属于其他地方,我们将添加一个globals.c
:
#include "globals.h"
int g_myGlobal;
应该有相应的globals.h
:
#ifndef _GLOBALS_H
#define _GLOBALS_H
extern int g_myGlobal;
#endif // _GLOBALS_H
在没有extern
的.h
文件中声明全局变量几乎可以肯定是错误的。如果您这样做,编译器将尝试在中声明每个包含该标头的C文件中的变量,这将导致链接时出现"多重定义"错误。(我想这就是为什么你问"foo.c总是包含bar123.h?",并解释了为什么它不重要。)
main.h
:
#include "globals.h"
int main() {
g_myGlobal = 42;
}
它的缩写就是这个。不能在头文件中包含全局,然后在其他地方包含该头。你会得到讨厌的"重新定义"错误。除非
这就是我的工作。
头文件happy.h
extern int happy; // Global variable
主文件
#include "happy.h"
int happy = 12;
其他文件.c
#include "happy.h"
int happy = 10;
关于问题2:这取决于编译器。有些人会隐含地添加它,然而,好的编码应该是包含任何要使用函数的.h文件的编码。
注意*将全局变量放在头中从来都不是一个好主意。标头的预期用途是结构定义和"public"函数声明。只有在必要时,结构/联合等定义才会包含在标头中。示例:
typedef struct
{
int happy;
char sad;
} my_mood_t;
my_mood_t *what_is_my_mood( int dog_ate_my_lunch );
来自OP的注释:
编译很好,但在运行时。('umac:openwrt路由器上的未知符号baz(错误0)'串行终端Tera Term(如果有帮助的话)
如果应用程序链接良好,但由于该错误而无法运行,则意味着在构建时链接期间,具有该符号的动态库是可用的。但是,在运行时,该符号不可用。快速解决方案:
- 确定具有符号的库
- 确保运行应用程序的位置存在库,并记下它的路径
- 不只是运行
application
,而是使用命令LD_LIBRARY_PATH=/path/to/the/library/directory application
(您也可以单独导出具有该值的LD_LIBRARY_PATH
,但它将为每个程序设置,而不仅仅是那个程序)
这不是唯一的方法。您也可以将库复制到系统库目录,然后运行ldconfig
来更新系统库缓存。或者你可以使用rpath机制。但是,在研究这些之前,先从LD_LIBRARY_PATH
环境变量开始,让事情正常工作。