What I write, what I lose.
以下为个人关于Linux下C程序的可扩张性的一点想法.
可扩展性的应用场景:
1. 有两个项目都需要使用的一个相同功能的程序, 但是有些要求不一样.
比如:升级程序, 一个是2个分区,一个是3个分区.
2. 具体使用的参数可能产生变化.
比如:服务器地址, 可能在开发阶段和正式上线阶段不同.
如何让程序具有可扩展性. 我理解到的增加可扩展的方式.
1.代码级别的修改.
比如针对服务器地址:
……
const char* server_url = “http://testserver:8080/service/xxInterface”;
https_post(server_url, ……);
……
当程序更新服务器地址为正式服务器后, 则在代码中找到对应的地方, 修改为
……
const char*server_url=“http://domainserver:8080/service/xxIterface”;
https_post(server_url, ……);
……
修改时需要找到所有使用此地址的变量. 全部加以修改.
2.代码级别的宏定义修改.
……
#define SERVER_URL “http://testserver:8080/service/xxInterface”;
……
https_post(SERVER_URL, ……);
……
当程序更新服务器地址为正式服务器后, 则只需要修改此一处宏定义即可.
这种方法修改比较简单. 但是缺点是需要手动更新源代码.
3.脚本控制/修改代码中的宏定义.
源代码中的一些宏定义是由脚本统一生成的. 修改此宏定义只需要修改对应的控制脚本或者控制脚本解析的文件. 然后由脚本生成源代码中的宏定义头文件.
具体的简单示例如下:
控制脚本config.sh 负责生成宏定义选项到 common_def.h头文件中.
common_def.h中定义程序需要使用到的宏定义选项.
具体实现的.c源代码include 头文件common_def.h.
修改宏定义则需修改config.sh或者控制脚本解析的文件 .执行脚本生成新的common_def.h头文件. 然后重新编译.
4.编译选项修改.
编译预处理时的宏定义由编译选项确定.
具体的简单示例如下:
代码中有:
#if DOMAIN_SERVER
const char* server_url = http://domainserver:8080/service/xxIterface;
#else
const char* server_url =“http://testserver:8080/service/xxIterface”;
#endif
DOMAIN_SERVER的定义不在源代码中设定, 而是在编译的时候有编译器选项确定.
gcc –o a.out -DDOMAIN_SERVER=1 src.c //打开#if DOMAIN_SERVER
gcc –o a.out -DDOMAIN_SERVER=0 src.c //关闭#if DOMAIN_SERVER
使用不同的编译选项重新编译即可让程序扩展使用不同的server_url.
5.硬编码配置文件.
在代码中增加一个配置信息模块. 程序需要的可配置信息从此模块中读取. 需要程序针对配置扩展修改时, 只需要修改此模块重新编译即可.
具体的简单示例如下:
update_config模块. update_config.c
……
add_config_item(“server_url”, “http://domainserver:8080/service/xxIterface”);
……
修改时只需要修改对应的update_config模块中的代码.
此方法跟统一宏定义的方法类似. 区别在于增加独立的配置信息模块.
6.动态配置文件.
程序在需要可配置信息时, 需要读取独立的配置文件, 解析此配置文件得到具体的配置信息.
具体的简单示例如下:
配置文件 update.conf:
server_url=http://domainserver:8080/service/xxIterface
配置信息模块解析文件update.conf. 得到server_url的值. 封装提供给其它模块使用.
配置文件的格式可自行设定. 如设置成键值对的文本文件, 或者xml格式都可以.
此方法的优点是不需要重新编译代码, 只需修改config配置文件即可使获得可扩展性.
7.使用环境变量
程序在需要使用可配置信息时, 使用getenv读取环境变量. 注意需要在程序运行之前设置该环境变量.
具体的简单示例如下:
run.sh是程序运行脚本. a.out是可执行程序, a.out需要使用server_url.
run.sh中内容
export SERVER_URL=http://domainserver:8080/service/xxIterface
./a.out
a.out实现.
const char* server_url = getenv(“SERVER_URL”);
……
此方法的优点是不需要重新编译代码, 只需要在程序运行前修改对应的环境变量定义.
8.使用可执行程序的参数
可执行程序在实际执行时, 可对参数进行解析, 根据不同的参数内容得到不同的可配置信息.
具体的简单示例如下:
a.out实现的时候先解析参数.
a.out –ddomainserver 解析为使用domainserver
a.out –dtestserver 解析为使用testserver
实际使用过程中, 可根据不同的应用场景, 使程序执行具有可扩展性.
以上, 谢谢......