在C代码文件中,我们经常会看到两类文件:
一类是:".h"文件
一类是:".c"文件
".h"文件,就是我们常说的头文件。
".c"文件,就是我们常说的源代码文件。
而在做开发的时候,经常不知道要把哪些东西放到".h"文件之中,又要把哪些东西放到".c"文件中。
今天就详细介绍一下这两个文件(".h"和".c")中都应该存放写什么东西。
首先,先介绍".h"文件。
".h"文件中存放的东西有:
1.include所需要的头文件。 如 #include<linux/pid.h>
2.宏定义。 如: #define SIZE 10;
3.类型的定义。 如: typedef struct student{} student
4.外部变量的声明。 如: extern struct task_struct *task;
extern spinlock_t spinlock;
5.函数的声明。 如: int sum(int a, int b
6.static inline函数。如:static inline sum(int a, int b);
以下是一个linux源码包中的头文件:
2 //头文件说明,用于防止头文件重名
3 #ifndef _LINUX_PID_H
4 #define _LINUX_PID_H
5
6 #include <linux/rcupdate.h>
7
8 //类型定义
9 enum pid_type
10 {
11 PIDTYPE_PID,
12 PIDTYPE_PGID,
13 PIDTYPE_SID,
14 PIDTYPE_MAX
15 };
16
17 struct upid {
18 /* Try to keep pid_chain in the same cacheline as nr for find_vpid */
19 int nr;
20 struct pid_namespace *ns;
21 struct hlist_node pid_chain;
22 };
23
24 struct pid
25 {
26 atomic_t count;
27 unsigned int level;
28 /* lists of tasks that use this pid */
29 struct hlist_head tasks[PIDTYPE_MAX];
30 struct rcu_head rcu;
31 struct upid numbers[1];
32 };
47 //外部变量的声明
48 extern struct pid init_struct_pid;
49 extern struct pid_namespace init_pid_ns;
50
51 //外部函数声明
52 extern void put_pid(struct pid *pid);
53 extern struct task_struct *pid_task(struct pid *pid, enum pid_type);
54 extern struct task_struct *get_pid_task(struct pid *pid, enum pid_type);
55 extern struct pid *get_task_pid(struct task_struct *task, enum pid_type type);
56 extern void attach_pid(struct task_struct *task, enum pid_type type,
57 struct pid *pid);
58 extern void detach_pid(struct task_struct *task, enum pid_type);
59 extern void change_pid(struct task_struct *task, enum pid_type,
60 struct pid *pid);
61 extern void transfer_pid(struct task_struct *old, struct task_struct *new,
62 enum pid_type);
64 // static inline 函数
65 static inline struct pid_namespace *ns_of_pid(struct pid *pid)
66 {
67 struct pid_namespace *ns = NULL;
68 if (pid)
69 ns = pid->numbers[pid->level].ns;
70 return ns;
71 }
72
73 static inline pid_t pid_nr(struct pid *pid)
74 {
75 pid_t nr = 0;
76 if (pid)
77 nr = pid->numbers[0].nr;
78 return nr;
79 }
81
82 //宏定义
83 #define do_each_pid_task(pid, type, task) \
84 do { \
85 struct hlist_node *pos___; \
86 if ((pid) != NULL) \
87 hlist_for_each_entry_rcu((task), pos___, \
88 &(pid)->tasks[type], pids[type].node) {
89
90 #define while_each_pid_task(pid, type, task) \
91 if (type == PIDTYPE_PID) \
92 break; \
93 } \
94 } while (0)
95
96 #define do_each_pid_thread(pid, type, task) \
97 do_each_pid_task(pid, type, task) { \
98 struct task_struct *tg___ = task; \
99 do {
100
101 #define while_each_pid_thread(pid, type, task) \
102 } while_each_thread(tg___, task); \
103 task = tg___; \
104 } while_each_pid_task(pid, type, task)
105 #endif /* _LINUX_PID_H */
".c"文件中存放的东西有:
1.需要的头文件。
2.全局变量。即头文件中的"extern int 变量名"声明的变量在这儿要进行定义与初始化;
3.只在本文件中使用的变量。即 static 变量类型
4.全局函数的实现。即头文件中的"extern int 函数名"声明的函数要在这儿进行实现。
5.局部函数的实现。即static 变量类型 函数名
linux源码中的".c"文件:
29 //包含的头文件
30 #include <linux/mm.h>
31 #include <linux/module.h>
32 #include <linux/slab.h>
33 #include <linux/init.h>
34 #include <linux/rculist.h>
35 #include <linux/bootmem.h>
36 #include <linux/hash.h>
37 #include <linux/pid_namespace.h>
38 #include <linux/init_task.h>
39 #include <linux/syscalls.h>
40
41 //只在本文件中使用的宏定义
42 #define pid_hashfn(nr, ns) \
43 hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
//定义只在本文件中使用的变量;
46 static struct hlist_head *pid_hash;
47 static unsigned int pidhash_shift = 4;
48
49 //全局变量的声明以及初始化,其他文件也可以使用,通过#include<linux/pid.h>即可
50 struct pid init_struct_pid = INIT_STRUCT_PID;
51
52 int pid_max = PID_MAX_DEFAULT;
53 int pid_max_min = RESERVED_PIDS + 1;
54 int pid_max_max = PID_MAX_LIMIT;
55 struct pid_namespace init_pid_ns = {
56 .kref = {
57 .refcount = ATOMIC_INIT(2),
58 },
59 .pidmap = {
60 [ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL }
61 },
62 .last_pid = 0,
63 .level = 0,
64 .child_reaper = &init_task,
65 };
66 EXPORT_SYMBOL_GPL(init_pid_ns);
68 //函数的实现,其他文件通过#include<linux/pid.h>就可以使用此函数;
69 int is_container_init(struct task_struct *tsk)
70 {
71 int ret = 0;
72 struct pid *pid;
73
74 rcu_read_lock();
75 pid = task_pid(tsk);
76 if (pid != NULL && pid->numbers[pid->level].nr == 1)
77 ret = 1;
78 rcu_read_unlock();
79
80 return ret;
81 }
82 EXPORT_SYMBOL(is_container_init);
83
84 //只能被本文件中的其他函数使用的函数。
85 static void free_pidmap(struct upid *upid)
86 {
87 int nr = upid->nr;
88 struct pidmap *map = upid->ns->pidmap + nr / BITS_PER_PAGE;
89 int offset = nr & BITS_PER_PAGE_MASK;
90
91 clear_bit(offset, map->page);
92 atomic_inc(&map->nr_free);
93 }