分类: C/C++
2009-05-07 21:13:20
第一篇:起步篇
千里之行,始于足下。
一、UNIX初步
UNIX自1969年诞生以来,已经发展为System III & V、BSD和Linux三大分支。
UniX通过shell与用户交互,它是用户与系统间的界面。使用好shell对于学习使用UNIX来说是必须的。不需要你记住所有的命令,但基础的文件操作、目录操作及系统命令等却是必须的。
Vi对于初学者是难点,不过只要通过一段时间的练习就能习惯;而且你会很快发现,它功能强大、更加灵活。这里不多说了:)
二、编程套件
学习UNIX对于初学者有几种选择。一种就是最直接的,在本机上安装UNIX系统,不如说Linux分支中的Red
Hat等;一种是在Windows环境下使用虚拟机方式安装UNIX系统;另一种则是使用网络终端登录到网络环境中的某个UNIX系统中。
如果你相对黑洞洞的UNIX字符界面更喜欢舒适美观的Windows界面,那么推荐你选择第三种方式。开发套件包括:编辑器UltraEdit、网络终端SecureCRT或其他。
编译器就不用说了,自然是cc(gcc或xlc系列)。这是C语言开发必不可少的。其中要注意-I(加载头文件路径)、-L(加载库文件路径)及-D(宏定义)参数的使用。
Make工具使用。如何编写makefile是关键。后面项目中使用时会详细介绍。
Gdb调试器。Gdb乃符号级调试工具,它控制程序的内部执行,利用断点设置、单步运行等手段,将程序的执行过程逐步展示在调试者目前。这种调试方式在短代码中可以发挥得很好。事实上,随着软件项目的扩大化、复杂化和分布化,很少有程序员直接通过Gdb等工具调试;使用日志记录调试方法比Gdb等调试工具更为便捷和广泛。
C工具:lint检查源代码是否正确,gprof分析程序时间消费量,cflow生成C语言流程图。
三、库的使用
库分静态库和动态库两种。
静态库的操作工具:ar命令。
编写及使用静态库:
(1)设计库源码pr1.c和pr2.c
[root@billstone
make_lib]# cat pr1.c void print1() { printf("This is the first lib
src!\n"); } [root@billstone make_lib]#
cat pr2.c void print2() { printf("This is the second src
lib!\n"); } |
[bill@billstone
make_lib]$ cc -O -c pr1.c pr2.c [bill@billstone make_lib]$
ls -l pr*.o -rw-rw-r-- 1 bill
bill 804 4月 15 11:11
pr1.o -rw-rw-r-- 1 bill
bill 804 4月 15 11:11
pr2.o |
(3) 链接静态库
为了在编译程序中正确找到库文件,静态库必须按照lib[name].a的规则命名,如下例中[name]=pr.
[bill@billstone
make_lib]$ ar -rsv libpr.a pr1.o pr2.o a - pr1.o a - pr2.o [bill@billstone make_lib]$
ls -l *.a -rw-rw-r-- 1 bill
bill 1822 4月 15 11:12
libpr.a [bill@billstone make_lib]$
ar -t libpr.a pr1.o pr2.o |
(4) 调用库函数代码main.c
[bill@billstone
make_lib]$ cat main.c int main() { print1(); print2(); return 0; } |
(5) 编译链接选项
-L及-l参数放在后面.其中,-L加载库文件路径,-l指明库文件名字.
[bill@billstone
make_lib]$ gcc -o main main.c -L./ -lpr [bill@billstone make_lib]$
ls -l main* -rwxrwxr-x 1 bill
bill 11805 4月 15 11:17
main -rw-rw-r-- 1 bill
bill 50 4月 15 11:15
main.c |
(6)执行目标程序
[bill@billstone
make_lib]$ ./main This is the first lib src! This is the second src lib! [bill@billstone
make_lib]$ |
编写动态库:
(1)设计库代码
[bill@billstone
make_lib]$ cat pr1.c int p = 2; void print(){ printf("This is the first dll
src!\n"); } [bill@billstone
make_lib]$ |
[bill@billstone
make_lib]$ gcc -O -fpic -shared -o dl.so pr1.c [bill@billstone make_lib]$
ls -l *.so -rwxrwxr-x 1 bill
bill 6592 4月 15 15:19
dl.so [bill@billstone
make_lib]$ |
[bill@billstone
make_lib]$ cat main.c int main() { print(); return 0; } [bill@billstone make_lib]$
gcc -o tdl main.c ./dl.so [bill@billstone make_lib]$
./tdl This is the first dll src! [bill@billstone
make_lib]$ |
[bill@billstone
make_lib]$ cat main.c #include int main() { void *pHandle; void (*pFunc)(); // 指向函数的指针 int *p; pHandle = dlopen("./d1.so",
RTLD_NOW); // 打开动态库 if(!pHandle){ printf("Can't find d1.so
\n"); exit(1); } pFunc = (void (*)())dlsym(pHandle,
"print"); // 获取库函数print的地址 if(pFunc) pFunc(); else printf("Can't find
function print\n"); p = (int *)dlsym(pHandle,
"p"); // 获取库变量p的地址 if(p) printf("p = %d\n",
*p); else printf("Can't find int
p\n"); dlclose(pHandle); // 关闭动态库 return 0; } [bill@billstone make_lib]$
gcc -o tds main.c -ldl [bill@billstone make_lib]$
./tds This is the first dll src! p = 2 [bill@billstone
make_lib]$ |