免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1083 | 回复: 0
打印 上一主题 下一主题

学习笔记01-学习《精通UNIX下C语言编程及项目实践》 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-15 10:06 |只看该作者 |倒序浏览

                                                                                                                                                                                                                                欢迎转载,请保留作者信息bill@华中科技大学
http://billstone.cublog.cn
第一篇:起步篇
  千里之行,始于足下。
一、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");
  }
  
  

  (2) 编译.c文件
[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]$
  
  

 (2)生成动态库

  
  
  [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]$
  
  

 当动态库的位置活名字发生改变时, 程序将无法正常运行; 而动态库取代静态库的好处之一则是通过更新动态库而随时升级库的内容.
动态库的显式调用: 显式调用动态库需要四个函数的支持, 函数dlopen打开动态库, 函数dlsym获取动态库中对象基址, 函数dlerror获取显式动态库操作中的错误信息, 函数doclose关闭动态库.

  
  
  [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]$
  
  

 上面的程序tds显式调用了共享库d1.so中的函数print和变量p.
 
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/47687/showart_1900487.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP