linux下动态库和静态库制作与调用 1.动态库和静态库简介 静态库是指在应用中,有一些公共代码需要反复使用,就把这些代码编译为“库”文件;在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中。这种库称为其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。
动态库又称动态链接库英文为dll,是指dynamiclinklibrary 的缩写形式,dll是一个包含可由多个程序同时使用的代码和数据的库,dll不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数
静态库:在编译的时候加载生成目标文件,在运行时不用加载库,在运行时对库没有依赖性。
动态库:在目标文件运行时加载,对库有依赖性。
1.1 linux下动态库和静态库命令方式
动态库命名方式:libxxx.so。其中so是shared objecd的缩写,即可以共享的目标文件,lib为库的固定格式,xxx为库名称,.so为动态库后缀。
动态库命名方式:libxxx.a xxx静态库名称。linux 上的静态库,其实是目标文件的归档文件。
1.2 编译生成共享库示例 命令:gcc -fpic -shared -o libxxx.so xxx.c
此过程分为编译和链接两部分,-fpic是编译选项,pic表示要生成位置无关的代码,这是动态库的特性,-shared是链接选项,告诉gcc生成动态库而不是可执行文件。
上述命令等同于:
gcc -fpic -c xxx.c
gcc -shared -o libxxx.so xxx.o
如下代码为例实现动态库编译与调用:
[wbyq@wbyq shared]$ gcc -fpic -shared -o libmyfile.so ./src/*.c -i./include gcc -i 指定头文路径
1.3 动态库调用[wbyq@wbyq shared]$ gcc main.c -iinclude -lmyfile -l./lib gcc -l 指定动态库路径
gcc -l 指定动态库名字
1.4 程序运行[wbyq@wbyq shared]$ ./a.out ./a.out: error while loading shared libraries: libmyfile.so: cannot open shared object file: no such file or directory 错误原因:
系统动态库默认搜索路径: /lib 和 /usr/lib
解决办法1:将libmyfile.so 拷贝到/usr/lib或者/lib目录下。
解决办法2:修改系统环境变量,动态库环境变量:ld_library_path
修改环境变量示例:
export ld_library_path=$ld_library_path:/mnt/hgfs/ubuntu/shared/lib 注意:在命令行修改环境变量只对当前终端有效。
解决办法2:修改系统启动文件
ubuntu下开机普通用户启动文件:~/.bashrc ~/.profile
管理员用户:/.profile
修改~/.bashrc文件:
同步文件:source ~/.bashrc
2 linux静态库创建与调用 2.1 linux静态库的命令规则 静态库libxxx.a xxx静态库名称。linux 上的静态库,其实是目标文件的归档文件。
2.2 linux静态库创建步骤 (1)编写源文件,通过gcc -c生成目标文件。
(2)用ar归档目标文件,生成静态库。
(3)配合静态库,写一个使用静态库中函数的头文件。
(4).使用静态库时,在源码中包含对应头文件,链接是记得链接自己的库。
2.3 生成静态库[wbyq@wbyq shared]$ ar t ./lib/libmyfile2.a #查看静态库信息my_cat.omy_cp.omy_du.o[wbyq@wbyq shared]$ gcc main.c -l./lib -lmyfile2 -o app -iinclude #调用静态 3.gcc编译器常用选项 3.1 gcc基本用法 使用 gcc编译器的时候,我们必须给出一系列必要的调用参数和文件名称。 gcc 编译器的调用参数大约有100 多个,这里只介绍其中最基本、最常用的参数。
gcc 最基本用法:gcc [参数] [文件名称]
3.2 常用参数 -c 只编译:不链接成为可执行文件,编译器只是由输入的.c 等源代码文件生成.o 为后缀的目标文件,通常用于编译不包含主程序的子程序文件。
-o output_filename:确定输出文件的名称为 output_filename,同时这个名称不能和源文件同名。如果不给出这个选项, gcc 就给出预设的可执行文件 a.out。
-g:产生符号调试工具(gnu 的 gdb)所必要的符号信息,要想对源代码进行调试,我们就必须加入这个选项。
-o:对程序进行优化编译、链接,采用这个选项,整个源代码会在编译、链接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、链接的速度就相应地要慢一些。
-o2:比-o 更好的优化编译、链接,当然整个编译、链接过程会更慢。
-e:仅执行编译预处理;
-s:将 c 代码转换为汇编代码;
3.3 编译时指定库文件和头文件路径 -l:指定动态库路径(可以指定多个路径)。
示例: gcc test.c -o app -l/usr/lib -l ./lib
-i:指定头文件存放的路径(可以指定多个路径)。
示例: gcc test.c -i ./ -i /include
-l:指定库名称(可以指定多个路径)。
示例: gcc test.c -l my_test -l func
4.linux下采用dlopen调用动态库 4.1 dlopen调用动态库意义 为了使程序方便扩展,具备通用性,可以采用插件形式。采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接库的形式加载进来,这就是所谓的插件。 linux 提供了加载和处理动态链接库的系统调用,非常方便。
生成动态库:gcc -fpic -shared libxxx.so -o xxx.c
4.2 dlopen系列函数介绍#include void *dlopen(const char *filename, int flags);函数功能:打开动态库形参:filename --动态库路径+名字 例:./lib/libmyfile.so flags --rtld_lazy使用时解析(暂缓解析) rtld_now --立刻解析返回值: handle --成功返回库引用信息,失败返回nullint dlclose(void *handle);函数功能:关闭动态库形参:handle --dlopen函数返回值void *dlsym(void handle, const charsymbol);函数功能:符号解析形参:handle --dlopen函数返回值 symbol --要解析的符号返回值:成功返回符号地址, 失败返回nullchar *dlerror(void); //打印错误信息 4.3函数解析示例#include ./include/my_file.h#include #include int main(){ int (*p)(const char *);//定义一个函数指针 /*打开动态库*/ void *handle=dlopen(./lib/libmyfile.so,rtld_lazy); if(handle==null) { printf(动态库解析失败%s\n,dlerror());//打印错误信息 return 0; } /*符号解析*/ p=dlsym(handle,my_cat); int res=p(main.c); printf(res=%d\n,res); p=dlsym(handle,my_du); p(main.c); //typedef unsigned int u32; typedef int (*my_cp)(const char *,const char *);//my_cp表示函数指针类型 my_cp test;//定义函数指针变量 test=dlsym(handle,my_cp); test(main.c,test.c); dlclose(handle);//关闭动态库} 4.4变量解析示例#include ./include/my_file.h#include #include int main(){ int (*p)(const char *);//定义一个函数指针 /*打开动态库*/ void *handle=dlopen(./lib/libmyfile.so,rtld_lazy); if(handle==null) { printf(动态库解析失败%s\n,dlerror());//打印错误信息 return 0; } /*符号解析*/ p=dlsym(handle,my_du); p(main.c); printf(-----------------------------------\n); /*解析变量*/ int *p2; p2=dlsym(handle,data); printf(*p2=%d\n,*p2); *p2=300; p(main.c); dlclose(handle);//关闭动态库}
物联网真相:需要的并不只是简单的物网相连
为什么同轴连接器中要使用铜这个导体
如何用最简单的方法解决TCP传输中的分包粘包问题?
光学薄膜之真空溅射镀膜技术详解
今年欧洲第三大融资 诺基亚手机制造商HMD融资2.3亿
Linux下动态库和静态库制作与调用
FOC驱动的Vq最大能给多少
三星的8nm工艺即将面临产能/良率问题
虹科干货 | HMI项目文件的加密和数字签名,你会了吗?
DRAM产业一掷千金 “存储教父”高启全能否扛起万亿重担
使用ES32实现CANopen从机
汽车电子域控制器一些问题以及探讨
荣耀V20支持4800万像素荣获年度拍照旗舰大奖拍照效果十分惊人
分布式设备管理有哪些痛点?如何打造设备智能管理系统?
基于物联网的智慧校园是什么样的?
集成电路芯片的作用 集成电路的分类
note7事件导致三星业务不景气 欲将PC业务出售给联想
机器学习——CNN如何进行图像分类
ASML已完成先进极紫外光刻机的设计
比亚迪电子迎真正增长时代 三大板块合力助推