Linux动态库生成与使用指南
相关阅读: Linux静态库生成指南
Linux下动态库文件的文件名形如 libxxx.so,其中so是 Shared Object 的缩写,即可以共享的目标文件。
在链接动态库生成可执行文件时,并不会把动态库的代码复制到执行文件中,而是在执行文件中记录对动态库的引用。
程序执行时,再去加载动态库文件。如果动态库已经加载,则不必重复加载,从而能节省内存空间。
Linux下生成和使用动态库的步骤如下:
- 编写源文件。
- 将一个或几个源文件编译链接,生成共享库。
- 通过
-L<path> -lxxx的gcc选项链接生成的libxxx.so。 - 把libxxx.so放入链接库的标准路径,或指定
LD_LIBRARY_PATH,才能运行链接了libxxx.so的程序。
下面通过实例详细讲解。
编写源文件
建立一个源文件: max.c,代码如下:
int max(int n1, int n2, int n3)
{
int max_num = n1;
max_num = max_num < n2? n2: max_num;
max_num = max_num < n3? n3: max_num;
return max_num;
}
编译生成共享库:
gcc -fPIC -shared -o libmax.so max.c
我们会得到libmax.so。
实际上上述过程分为编译和链接两步, -fPIC是编译选项,PIC是 Position Independent Code 的缩写,表示要生成位置无关的代码,这是动态库需要的特性; -shared是链接选项,告诉gcc生成动态库而不是可执行文件。
上述的一行命令等同于:
gcc -c -fPIC max.c
gcc -shared -o libmax.so max.o
为动态库编写接口文件
为了让用户知道我们的动态库中有哪些接口可用,我们需要编写对应的头文件。
建立 max.h ,输入以下代码:
#ifndef __MAX_H__
#define __MAX_H__
int max(int n1, int n2, int n3);
#endif
测试,链接动态库生成可执行文件
建立一个使用max函数的test.c,代码如下:
#include <stdio.h>
#include "max.h"
int main(int argc, char *argv[])
{
int a = 10, b = -2, c = 100;
printf("max among 10, -2 and 100 is %d.\n", max(a, b, c));
return 0;
}
gcc test.c -L. -lmax 生成a.out,其中-lmax表示要链接libmax.so。
-L.表示搜索要链接的库文件时包含当前路径。
注意,如果同一目录下同时存在同名的动态库和静态库,比如 libmax.so 和 libmax.a 都在当前路径下,
则gcc会优先链接动态库。
运行
运行 ./a.out 会得到以下的错误提示。
./a.out: error while loading shared libraries: libmax.so: cannot open shared object file: No such file or directory
找不到libmax.so,原来Linux是通过 /etc/ld.so.cache 文件搜寻要链接的动态库的。
而 /etc/ld.so.cache 是 ldconfig 程序读取 /etc/ld.so.conf 文件生成的。
(注意, /etc/ld.so.conf 中并不必包含 /lib 和 /usr/lib,ldconfig程序会自动搜索这两个目录)
如果我们把 libmax.so 所在的路径添加到 /etc/ld.so.conf 中,再以root权限运行 ldconfig 程序,更新 /etc/ld.so.cache ,a.out运行时,就可以找到 libmax.so。
但作为一个简单的测试例子,让我们改动系统的东西,似乎不太合适。
还有另一种简单的方法,就是为a.out指定 LD_LIBRARY_PATH。
LD_LIBRARY_PATH=. ./a.out
程序就能正常运行了。LD_LIBRARY_PATH=. 是告诉 a.out,先在当前路径寻找链接的动态库。
对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的
DT_RPATH段, 环境变量LD_LIBRARY_PATH, /etc/ld.so.cache文件列表, /lib/,/usr/lib目录, 找到库文件后将其载入内存. (http://blog.chinaunix.net/uid-23592843-id-223539.html)
makefile让工作自动化
编写makefile,内容如下:
.PHONY: build test clean
build: libmax.so
libmax.so: max.o
gcc -o $@ -shared $<
max.o: max.c
gcc -c -fPIC $<
test: a.out
a.out: test.c libmax.so
gcc test.c -L. -lmax
LD_LIBRARY_PATH=. ./a.out
clean:
rm -f *.o *.so a.out
make build就会生成libmax.so, make test就会生成a.out并执行,make clean会清理编译和测试结果。
2015-03-11 Wed
Linux动态库生成与使用指南的更多相关文章
- Linux动态库生成以及调用
Linux下动态库文件的文件名形如 libxxx.so,其中so是 Shared Object 的缩写,即可以共享的目标文件. 在链接动态库生成可执行文件时,并不会把动态库的代码复制到执行文件中,而是 ...
- Linux静态库生成指南
Linux静态库生成指南 Linux上的静态库,其实是目标文件的归档文件.在Linux上创建静态库的步骤如下: 写源文件,通过 gcc -c xxx.c 生成目标文件. 用 ar 归档目标文件,生 ...
- Linux下动态库生成和使用
Linux下动态库生成和使用 一.动态库的基本概念 1.动态链接库是程序运行时加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序.动态链接库是目标文件的集合,目标文件在动态链接库中 ...
- linux动态库默认搜索路径设置的三种方法
众所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/lib .动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两 ...
- 技巧:Linux 动态库与静态库制作及使用详解
技巧:Linux 动态库与静态库制作及使用详解 标准库的三种连接方式及静态库制作与使用方法 Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 L ...
- linux动态库加载RPATH, RUNPATH
摘自http://gotowqj.iteye.com/blog/1926771 linux动态库加载RPATH, RUNPATH 链接动态库 如何程序在连接时使用了共享库,就必须在运行的时候能够找到共 ...
- linux动态库编译和使用
linux动态库编译和使用详细剖析 引言 重点讲述linux上使用gcc编译动态库的一些操作.并且对其深入的案例分析.最后介绍一下动态库插件技术, 让代码向后兼容.关于linux上使用gcc基础编译, ...
- Android NDK开发及调用标准linux动态库.so文件
源:Android NDK开发及调用标准linux动态库.so文件 预备知识及环境搭建 1.NDK(native development Kit)原生开发工具包,用来快速开发C.C++动态库,并能自动 ...
- windows动态库与Linux动态库
Linux动态库和windows动态库的目的是基本一致的,但由于操作系统的不同,他们在许多方面还是不尽相同.但是尽管有差异Linux动态库的windows动态库还是可以移植的,有一些规则以及经验是必须 ...
随机推荐
- eclipse去除对js文件的检测
- JS第二部分--DOM文档对象模型
一.DOM的概念 二.DOM可以做什么 三.DOM对象的获取 四.事件的介绍 五.DOM节点标签样式属性的操作 六.DOM节点对象对值的操作 七.DOM节点-标签属性的操作(例如id class sr ...
- bibli直播弹幕实时爬取
1 分析数据来源 在不知道弹幕信息在哪里的时候,只能去all里面查看每一个相应的信息,看信息是否含有弹幕信息 在知道弹幕信息文件的时候,我们可以直接用全局文件搜索,定位到弹幕数据文件.操作如下图 2 ...
- Django 之 admin管理工具
-------------------------------------------------------------------------妄尝恶果,苦果自来. admin组件使用 Django ...
- MySQL RPM二进制安装
+++++++++++++++++++++++++++++++++++++++++++标题:MySQL RPM二进制安装时间:2019年2月24日内容:MySQL RPM二进制安装重点:MySQL R ...
- 对List集合嵌套了map集合对double值进行排序
/*[ { "repairo": "asda", "num": 88.71 }, { "repairo": " ...
- spring异常Unsatisfied dependency expressed through constructor parameter 0
异常信息: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with nam ...
- 搭建Android手机服务器(一)
自从上学期的软件工程课之后,我们团队设计的抢答器一直想把服务端移到移动端.所以,我一直在考虑如何把手机作为一台服务器.今天我主要讲解一下,对于没有android真机只有模拟器的,如何设置模拟器,使得在 ...
- 4月10日java多线程3
在之前我学习了java中的Thread 来实现多线程,今日我学习了ThreadGroup.Executor框架.ForkJoin框架.Executor 和ForkJoin都可以直接定义线程池,可以根据 ...
- VMware Workstation 10序列号:
VMware Workstation 10序列号:1Y0LW-4WJ9N-LZ5G9-Z81QP-92PN7