Linux TCP/IP协议栈的通用编码模式解析

时间:2007-05-26 07:41:51  来源:站长资讯收集整理  作者:佚名

因此,如果abc在不同的代码中被使用,每一个代码都使用相同的基本定义(避免做同样的事情而采用不同的方法),同时可以根据自己的需求来扩展abc。

1.2.8. 条件编译 (#ifdef and family)

编译器的条件编译有时很有必要。过度地使用条件编译会降低代码的可读性,但是我可以声明,linux内核没有滥用它们。条件编译可以在多种情况下使用,但是我们感兴趣的是它用于检查内核是否支持某一特性。make xconfig这样配置工具会决定某一特性是编译到内核,或者完全不支持,或者编译成内核模块。

使用#ifdef或#if defined检查内核是否支持某一特性的例子如下:

包含或者不包含数据结构的某个成员

struct sk_buff {

...

#ifdef CONFIG_NETFILTER_DEBUG

unsigned int nf_debug; #endif

...

}

在这个例子中,netfilter的调试功能需要sk_buff结构中的nf_debug项。如果内核不支持netfilter

调试功能(只有一小部分开发人员需要这项功能),就没必要包含这一项, 否则它只会使得每个网络包占用更多的内存。

函数中,包含或不包含某段代码

int ip_route_input(...)

{

...

if (rth->fl.fl4_dst == daddr &&

rth->fl.fl4_src == saddr &&

rth->fl.iif == iif &&

rth->fl.oif == 0 &&

#ifndef CONFIG_IP_ROUTE_FWMARK

rth->fl.fl4_fwmark == skb->nfmark &&

#endif

rth->fl.fl4_tos == tos) {

...

}

}

为一个函数选择正确的原型

#ifdef CONFIG_IP_MULTIPLE_TABLES

struct fib_table * fib_hash_init(int id)

#else

struct fib_table * _ _init fib_hash_init(int id)

{

...

}

为函数选择正确的定义

#ifndef CONFIG_IP_MULTIPLE_TABLES ... static inline struct fib_table *fib_get_table(int id)

{

if (id != RT_TABLE_LOCAL)

return ip_fib_main_table;

return ip_fib_local_table

} ...

#else

...

static inline struct fib_table *fib_get_table(int id)

{

if (id == 0)

id = RT_TABLE_MAIN;

return fib_tables[id]; }

...

#endif

请注意这个例子和前一个例子的区别。在前一个例子中,函数体在 #ifdef/#endif 块之外, 而这个例子中,每一块都包含一个完整的函数定义。

变量定义或初始化,还有宏,都可以使用条件编译。

知道某个函数或宏有多个定义非常重要,具体使用哪个函数或者宏与条件编译有关,前面就有这样的例子。否则,你看的函数,变量或者宏的定义可能不是你所希望看到的那个。

文章评论

共有 位CH网友发表了评论 查看完整内容