C 函数库及头文件
2016-11-04 12:22
127 查看
1 函数库
库本质上是一种经过编译的可执行二进制代码,可以被操作系统载入内存执行。Linux 和 Windows 等不同平台编译环境不同, 函数库不兼容。
1.1 静态库 Static Library
静态是指每个用到该库的应用程序都拥有一份自己的库拷贝静态库在程序编译时会被连接到目标代码中,可执行程序的体积较大, 程序运行时将不再需要该静态库, 可以删除库文件
静态库生成: 使用 ar (archive)命令将 .o 文件转换成 .a 静态库文件
静态库命名规则: 静态库的名字一般为 libxxxx.a, 其中 xxxx 是该库的名称, 后缀名是 .a
1.1.1 静态库查找
静态库文件一般放在/lib,
/usr/lib和
/usr/local/lib下, ld 默认能够找到, 无需其他操作
将静态库文件路径添加到
/etc/ld.so.cache文件中, 执行 ldconfig 命令添加指定目录, 重建
/etc/ld.so.cache文件, 使该函数库被系统共享
1.1.2 静态库的生成
使用 ar 命令创建静态库options | explanation |
---|---|
r | 替换已存在的或添加新文件到库中 |
s | 作为 ranlib |
c | 如果库必须被创建,不要发出告警 |
1.2 共享库 Shared library
共享库现在常常被叫做动态库, 是由于很多人借用了 Windows 的 DLL (Dynamic Linked Library) 这个词共享库在程序编译时并不会被连接到目标代码中, 而是在程序运行是才被载入, 因此在程序运行时还需要动态库存在
一个共享库有可能被多个所有应用程序共享。因此,对每个应用程序来说,即使不再使用某个共享库,也不应将其删除
应用程序需要正确的环境变量设置(LD_LIBRARY_PATH),从而添加并找到共享库所在的位置,否则,应用程序运行时会报告找不到这个库
共享库的代码是在可执行程序运行时才载入内存的,在编译过程中只是简单的引用,因此代码体积较小
共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例
共享库命名规则: 共享库的名字一般为 libxxxx.so.major.minor, 其中 xxxx 是该库的名称, major 是主版本号, minor 是副版本号, 后缀名是.so
使用 ldd(list dependencies) 命令可以查看一个可执行程序依赖的共享库, 或者说程序调用共享库的过程
使用 gcc 编译器的 -v 选项打印路径搜索过程
当静态库和动态库同名时, gcc 命令将优先使用动态库
2.2.1 共享库查找
当系统加载可执行代码时候, 能够知道其所依赖的共享库的名字elf 格式的可执行程序通过系统动态载入器(dynamic linker/loader)获取共享库的绝对路径, 搜索到共享库将其载入内存
动态载入器命名规则: ld-linux.so*
共享库查找顺序: elf 文件的 DT_RPATH 段指定的路径->LD_LIBRARY_PATH 环境变量指定的路径->/etc/ld.so.cache 文件列表->/lib 和 /usr/lib 目录下的文件
2.2.2 共享库的生成
# gcc -shared -fPIC -o libmyhello.so hello.o
使用 gcc 命令创建共享库 libmyhello.so
“PIC” 命令行标记告诉 gcc 产生的代码不要包含对函数和变量具体内存位置的引用,因为现在还无法知道使用该消息代码的应用程序会将它连接到哪一段内存地址空间。这样编译出的 hello.o 可以被用于建立共享链接库。
建立共享链接库只需要用 gcc 的 ”-shared” 标记即可。
2.2.3 共享库的使用
# gcc -o hello main.c -L. -lmyhello
在使用到这些库函数的源程序中包含这些库函数的原型声明
在用 gcc 命令生成目标文件时指明动态库名进行编译。调用动态链接库编译目标文件。
使用”-lmyhello”标记来告诉GCC驱动程序在连接阶段引用共享函数库libmyhello.so
使用”-L.”标记告诉GCC函数库可能位于当前目录。否则GNU连接器会查找标准系统函数目录.
共享库查找相关环境变量
LIBRARY_PATH: 编译时使 gcc 能够找到编译时需要的动态链接库LD_LIBRARY_PATH: 程序加载运行时能够自动找到需要的动态链接库
注意编译时指定共享库目录,可以编译通过,不代表运行时还能查找到这个库,因此编译时用-L指定,运行时要加入 ld.so.cache 文件
查考库函数所用的环境变量
LIBRARY_PATH 指明库搜索路径,此环境变量指明路径会在-L指定路径之后,系统默认路径之前被搜索。内核态和用户层的共享库
.ko, .so 都是动态库.ko -- kernel object,内核模块,可以在Linux内核起来之后动态的加载和卸载。
.so -- shared object,用户层的动态库 (于.a 对应),使用同一个.so的程序在运行时
只需要该.so的同一份拷贝。
关于.ko,上面有范例了。在Linux Device Driver 3rd那本书上也有说明。
至于.so,这里有例子:
http://blog.csdn.net/thinkerABC/archive/2006/03/11/621817.aspx
另外,如果你有 《C专家编程》这本书,也可以看看 “第五章 对链接的思考”
2 头文件概述
使用双引号形式包含用户定义头文件, 使用尖括号形式包含系统头文件指定头文件目录影响的是预处理器的行为, 指定库文件路径影响的是连接器的行为
2.1 头文件查找过程
双引号指定目录(程序中显式指定的目录)编译命令指定目录(gcc 编译器的 -iquote 和 -I 选项)
环境变量指定目录(交叉编译工具链)
标准系统包含目录(操作系统)
2.2 查找头文件所用的环境变量
gcc 编译器的环境变量| variables | describe | | ------------------ | -------- | | CPATH | 指定搜索的目录列表, 效果同 -I 选项, 3种 C 语言通用 | | C_INCLUDE_PATH | 指定搜索的目录列表, 效果同 -isystem 选项, 仅适用于 C 语言 | | CPLUS_INCLUDE_PATH | 同上, 仅适用于 C++ | | OBJC_INCLUDE_PATH | 同上, 仅适用于 Objective C |
2.3 标准系统目录 standard system include Directory
/usr/include /usr/local/include
参考
LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别Linux下Gcc生成和使用静态库和动态库详解(转)
C/C++ 头文件以及库的搜索路径
C语言头文件、库文件的查找路径 - c语言程序开发技术文章 - 红黑联盟
动态链接库.ko与.so的区别???怎么生成制作.ko文件 ???
相关文章推荐
- sort()函数与qsort()函数及其头文件
- Linux内核开发常用函数及其头文件
- stdlib.h头文件下的常用函数
- C语言的头文件和库文件(函数库)
- iomanip头文件常用函数汇总
- 怎么查找一些函数对应的头文件
- 新手第二课:atof()函数的头文件
- 这么详细的分类 VC/C++源代码网站你见过没有? VC/C++中的每一个方法,每一个操作,每一个头文件,每一个函数,每一个类.每一个属性,每一个事件都有相应的范例代码
- 在不改变基类头文件的前提下,使用基类成员函数
- ACM头文件、常用函数、宏定义
- C语言笔记——头文件string.h中内置的常用字符串操作函数
- 大三时候实现的,关于大整数(超过long范围)加减乘除操作的头文件,并包含了实现RSA加解密的函数
- Math.Inc 分型图形库数学函数头文件 数字函数+向量和矩阵函数+仿射变换
- C语言中自带的头文件(.h)所包含的函数
- 这么详细的分类 PHP源代码网站你见过没有? PHP中的每一个方法,每一个操作,每一个头文件,每一个函数,每一个类.每一个属性,每一个事件都有相应的范例代码
- sort()函数与qsort()函数及其头文件
- inline函数必须定义在头文件吗
- c++常用函数所在头文件一览
- C语言中自带的头文件(.h)所包含的函数
- 这么详细的分类 C++ 源代码网站你见过没有? C++ 中的每一个方法,每一个操作,每一个头文件,每一个函数,每一个类.每一个属性,每一个事件都有相应的范例代码