现在的位置: 首页 > 综合 > 正文

Beginning Linux Programming Third Edition

2013年10月15日 ⁄ 综合 ⁄ 共 2981字 ⁄ 字号 评论关闭

转自 http://blog.csdn.net/liuzhuan_1986/article/details/4323274

作为Linux程序开发员,最好对开发工具和资源的位置有个初步了解。下面简要介绍一下主要的文件夹和应用程序。

应用程序(Applications)

应用程序通常都有固定的文件夹,系统通用程序放在/usr/bin,日后系统管理员在本地计算机安装的程序通常放在/usr/local/bin或者/opt文件夹下。除了系统程序外,大部分个人用到的程序都放在/usr/local下,所以保持/usr的整洁十分重要。当升级或者重装系统的时候,只要把/usr/local的程序备份一下就可以了。

一些其他的程序有自己特定的文件夹,比如X Window系统,通常安装在/usr/X11中,或者/usr/X11R6。GNU的编译器GCC,通常放置在/usr/bin或者/usr/local/bin中,不同的Linux版本可能位置稍有不同。

头文件(Head Files)

在C语言和其他语言中,头文件声明了系统函数和库函数,并且定义了一些常量。对于C语言,头文件基本上散落于/usr/include和它的子文件夹下。其他的编程语言的库函数分布在编译器定义的地方,比如在一些Linux版本中,X Window系统库函数分布在/usr/include/X11,GNU C++的库函数分布在/usr/include/g++。这些系统库函数的位置对于编译器来说都是“标准位置”,即编译器能够自动搜寻这些位置。

如果想引用位于标准位置之外的头文件,我们需要在调用编译器的时候加上-I标志,来显式的说明头文件所在文件夹。比如,

        $ gcc -I/usr/openwin/include hello.c

会告诉编译器除了标准位置外,还要去/usr/openwin/include看看有没有所需的头文件。详细情况见编译器的使用手册(man gcc)。


库函数(Library Files)

库函数就是函数的仓库,它们都经过编译,重用性不错。通常,库函数相互合作,来完成特定的任务。比如操控屏幕的库函数(cursers和ncursers库函数),数据库读取库函数(dbm库函数)等。

系统调用的标准库函数一般位于/lib以及/usr/lib。C编译器(精确点说,连接器)需要知道库函数的位置。默认情况下,它只搜索标准C库函数。

库函数文件通常开头字母是lib。后面的部分标示库函数的用途(比如C库函数用c标识, 数学库函数用m标示),小数点后的后缀表明库函数的类型:

  • .a 指静态链接库
  • .so 指动态链接库

去/usr/lib看一下,你会发现,库函数都有动态和静态两个版本。

与头文件一样,库函数通常放在标准位置,但我们也可以通过-L标识符,来添加新的搜索文件夹,-l指定特定的库函数文件。比如

        $ gcc -o x11fred -L/usr/openwin/lib x11fred.c -lX11

上述命令就会在编译期间,链接位于/usr/openwin/lib文件夹下的libX11函数库,编译生成x11fred。

 

静态链接库(Static Libraries)

最简单的函数库就是一些函数的简单集合。调用库函数中的函数时,需要在调用函数中include定义库函数的头文件。我们用-l选项添加标准函数库之外的函数库。

静态函数库,也称为archives,通常以后缀.a结尾。

我们也可以创建维护自己的静态链接库函数。下面就介绍一下:

我们创建的库函数包括两个函数,然后在后面的实例中调用其中之一。两个库函数名字分别是fred和bill,仅仅是输出字符串。

  1. 首先,我们分别编写两个源文件(fred.c和bill.c),源文件如下:
  1. /* fred.c */  
  2. #include <stdio.h>  
  3. void fred(int arg)  
  4. {  
  5. printf(“fred: you passed %d/n”, arg);  
  6. }  
  7. /* bill.c */  
  8. #include <stdio.h>  
  9. void bill(char *arg)  
  10. {  
  11. printf(“bill: you passed %s/n”, arg);  
  12. }  

    2. 接下来,我们将这两个源文件编译为两个独立的目标文件。这里要用到GCC的-c选项。命令如下所示:

        $ gcc -c fred.c bill.c

        $ ls *.o

        bill.o fred.o

 

    3. 然后,写一个调用bill的测试函数,在此之前,最好为库函数建立一个头文件。头文件中有对库函数的声明。如果其他函数要调用库函数,必须在其代码中包含头文件。也可以在fred.c 和bill.c中包含该头文件,有利于编译器发现错误。头文件lib.h的内容如下所示:

[c-sharp] view
plain
copy

  1. /* 
  2. This is lib.h. It declares the functions fred and bill for users 
  3. */  
  4. void bill(char *);  
  5. void fred(int);  

 

    4. 测试函数program.c比较简单,代码如下:

[c-sharp] view
plain
copy

  1. #include “lib.h”  
  2. int main()  
  3. {  
  4.     bill(“Hello World”);  
  5.     exit(0);  
  6. }  

    5. 现在我们可以编译测试一下程序了:

        $ gcc -c program.c

        $ gcc -o program program.o bill.o

        $ ./program

        bill: we passed Hello World

        $

 

    6. 接下来,我们要创建一个函数库。利用ar函数建立归档文件(archive),然后将目标文件加入其中。

        $ ar crv libfoo.a bill.o fred.o

        a - bill.o

        a - fred.o

 

    7. 现在可以使用函数库中的函数了。我们用-l指定函数库的名字。因为该函数库没有在标准文件夹中,我们还需要用-L将当前文件夹"."添加到搜索路径中。编译命令如下所示:

        $ gcc -o program program.o -L. -lfoo

 

共享链接库(Shared Libraries)

静态链接库的一个缺点是,如果我们同时运行了许多程序,并且它们使用了同一个库函数,这样,在内存中会大量拷贝同一库函数。这样,就会浪费很多珍贵的内存和存储空间。使用了共享链接库的Linux就可以避免这个问题。

共享函数库和静态函数在同一个地方,只是后缀有所不同。比如,在一个典型的Linux系统,标准的共享数序函数库是/usr/lib/libm.so。

当一个程序使用共享函数库时,在连接阶段并不把函数代码连接进来,而只是链接函数的一个引用。当最终的函数导入内存开始真正执行时,函数引用被解析,共享函数库的代码才真正导入到内存中。这样,共享链接库的函数就可以被许多程序同时共享,并且只需存储一次就可以了。共享函数库的另一个优点是,它可以独立更新,与调用它的函数毫不影响。

抱歉!评论已关闭.