标c-02-基础知识-动态库和共享库

day02:静态库 和共享库(动态库)

c程序员的错误处理

环境变量和环境表

详细笔记如下:

一个操作系统是非常复杂的,提供非常多的系统函数,如何管理这些系统函数:比如:函数 a()究竟来自哪个.o件?                                                                                    需要把所有的.o文件打包,打包成静态库或共享库

静态库(.a) 共享库(.so)

静态库和共享库的区别:

静态库是代码的一个归档,在使用静态库的时候,采用的复制代码的方式。

共享库是可执行文件的执行组成部分,在使用共享库时是采用提供代码在共享库的地址 给可执行文件的方式。

静态库和共享库的优缺点:

静态库的优点就是完全独立,代码链接后再运行时不再需要静态库的参与,同时效率稍高,缺点是 占用空间大,修改和维护不方便。

共享库的优点是 占用空间小,修改和维护方便,缺点就是不独立,运行时需要可执行文件和共享库同时参与,效率稍低

静态库的创建和使用步骤:

创建步骤:

1.写源文件.c,保存退出

2.编译源文件,生成xxx.o文件

gcc -c xxx.c

3.用ar -r 命令生成静态库文件.a

ar -r lib库名.a xxx.o

静态库文件有命名规范,以lib开头,以.a结束,中间是库名

调用步骤:

1.写调用的源文件.c,保存退出,这里要导入包含函数声明的头函数

2.编译连接源文件和静态库文件,有三种方式:

2.1 直接连接法 gcc test.c 库文件名(libtest.a)

gcc test.c libmyku.a

2.2 双L连接法 gcc test.c -l库名 -L库所在的路径

库名不包括lib 和.a  gcc test.c -lmyku -L.

2.3单l连接法 需要先配置环境变量LIBRARY——PATH,把库文件所在的路径配置进来,然后用l就可以了

export LIBRARY_PATH=.

gcc test.c -lmyku

注意:提供库文件的程序员,必须同时提供头文件。

共享库的创建和使用步骤:

创建步骤:

1 编写源文件,保存退出

2 编译源文件,生成.o文件 gcc -c -fpic xxx.c

3 生成共享库文件  gcc -shared xxx.o -olibmyku.so

ps:共享库是可执行文件的一部分

使用步骤和静态库完全一样,但是要配置环境变量

注意:共享库在运行时会参与进来,因此在运行时,必须保证能找到共享库,需要配置环境变量LD_LIBRARY_PATH.

指令:export LD_LIBRARY_PATH=.

Unix系统提供了一系列的共享库和头文件,代码出自共享库,函数的函数声明出自头文件,指令:ldd a.out 就可以查看相关的库文件都有哪些

C程序员的错误处理-错误处理不可怕,是 程序员必须面对的,是软件编程的一个组成部分

不是所有的错误都可以处理。但可以处理的错误必须考虑如何处理。

后期的计算机语言(C++/JAVA)都是采用异常机制进行错误处理(Exception),但是C语言没有异常机制,C程序员用返回值标识错误。

关于返回值,有以下4种情况:

1 如果函数的返回值是int ,并且返回的数据不可能是负数 ,返回-1,代表出错了,其他数据正常返回。

2.如果函数的返回值是int,并且返回的数据可能是负数,用返回0 代表没有错,用返回 -1 代表出错,数据用 指针返回

3 如果函数的返回值是指针,用NULL 代表出错,个别函数也用 (void*)-1 代表出错。

4.如果函数不可能出错,或不需要考虑错误处理,返回值不着任何的改变

以上始终情况,只是c程序员的一般情况,也有特例存在

C官方提供了一个变量和三个函数,用于错误的显示和处理;

c语言存储的都是错误编号,而如果想知道是什么错误,必须查看编号对应的错误信息,错误编号存在外部全局变量errorno,错误编号转错误信息的函数有:

strerror() - 传入错误编号 返回错误信息,不打印

perror()  -自动打印errno 对应的错误信息并换行() (没有发生的错误无法查看)

printf("%m") 自动打印errorno对应的错误信息 ,了解

如果代码出错了,会改变errno的值,记录错误编号,如果代码没有出错,errno是不会改变的,因此不能用errorno判断是否出错。errorno是用来记录错误信息的,返回值是用来判断时候出错的。

c程序员处理错误的一般流程:

用返回值判断时候出错,如果出错,调用perror()打印错误信息,并进行错误分支的代码编程。

注:不是所有的函数都支持errorno,有些函数就没有使用errno,比如线程相关的函数都没有使用

环境变量和环境表

程序员如何操作环境,命令也是程序员写的程序

环境表是字符指针数组,char* arr[],是所以环境变量在内存中的首地址。字符指针数组可以用char**(二级指针)表示。很多时候环境表就是使用二级指针表示。

extern char** environ;就可以直接获得环境表的首地址。

environ也是也各外部的全局变量,但是在声明时没有加上extern,因此需要调用者自己加。extern代表全局变量来自于其他文件中。

environ一般都不直接参与指针的移动,而是用一个局部变量 代替environ进行指针的移动,因为environ是所有的程序公用的。

指针的算数运算(加法和减法)移动的字节数由 指向的数据类型的大小决定,指向int,移动sizeof(int)字节(加1的情况下)。

你可能感兴趣的:(标c-02-基础知识-动态库和共享库)