相关阅读: Linux静态库生成指南

Linux下动态库文件的文件名形如 libxxx.so,其中so是 Shared Object 的缩写,即可以共享的目标文件。

在链接动态库生成可执行文件时,并不会把动态库的代码复制到执行文件中,而是在执行文件中记录对动态库的引用。

程序执行时,再去加载动态库文件。如果动态库已经加载,则不必重复加载,从而能节省内存空间。

Linux下生成和使用动态库的步骤如下:

  1. 编写源文件。
  2. 将一个或几个源文件编译链接,生成共享库。
  3. 通过 -L<path> -lxxx 的gcc选项链接生成的libxxx.so。
  4. 把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.solibmax.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/libldconfig程序会自动搜索这两个目录)

如果我们把 libmax.so 所在的路径添加到 /etc/ld.so.conf 中,再以root权限运行 ldconfig 程序,更新 /etc/ld.so.cachea.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.somake test就会生成a.out并执行,make clean会清理编译和测试结果。

2015-03-11 Wed

Linux动态库生成与使用指南的更多相关文章

  1. Linux动态库生成以及调用

    Linux下动态库文件的文件名形如 libxxx.so,其中so是 Shared Object 的缩写,即可以共享的目标文件. 在链接动态库生成可执行文件时,并不会把动态库的代码复制到执行文件中,而是 ...

  2. Linux静态库生成指南

    Linux静态库生成指南   Linux上的静态库,其实是目标文件的归档文件.在Linux上创建静态库的步骤如下: 写源文件,通过 gcc -c xxx.c 生成目标文件. 用 ar 归档目标文件,生 ...

  3. Linux下动态库生成和使用

    Linux下动态库生成和使用 一.动态库的基本概念 1.动态链接库是程序运行时加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序.动态链接库是目标文件的集合,目标文件在动态链接库中 ...

  4. linux动态库默认搜索路径设置的三种方法

    众所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/lib .动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两 ...

  5. 技巧:Linux 动态库与静态库制作及使用详解

    技巧:Linux 动态库与静态库制作及使用详解 标准库的三种连接方式及静态库制作与使用方法 Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 L ...

  6. linux动态库加载RPATH, RUNPATH

    摘自http://gotowqj.iteye.com/blog/1926771 linux动态库加载RPATH, RUNPATH 链接动态库 如何程序在连接时使用了共享库,就必须在运行的时候能够找到共 ...

  7. linux动态库编译和使用

    linux动态库编译和使用详细剖析 引言 重点讲述linux上使用gcc编译动态库的一些操作.并且对其深入的案例分析.最后介绍一下动态库插件技术, 让代码向后兼容.关于linux上使用gcc基础编译, ...

  8. Android NDK开发及调用标准linux动态库.so文件

    源:Android NDK开发及调用标准linux动态库.so文件 预备知识及环境搭建 1.NDK(native development Kit)原生开发工具包,用来快速开发C.C++动态库,并能自动 ...

  9. windows动态库与Linux动态库

    Linux动态库和windows动态库的目的是基本一致的,但由于操作系统的不同,他们在许多方面还是不尽相同.但是尽管有差异Linux动态库的windows动态库还是可以移植的,有一些规则以及经验是必须 ...

随机推荐

  1. spring boot拦截器中获取request post请求中的参数(转)

    文章转自 https://www.jianshu.com/p/69c6fba08c92

  2. MyExceptionFilter 异常注入

    public class MyExceptionFilter : IExceptionFilter { private ILogService logService; public MyExcepti ...

  3. Luogu P5280 [ZJOI2019]线段树

    送我退役的神题,但不得不说是ZJOIDay1最可做的一题了 先说一下考场的ZZ想法以及出来后YY的优化版吧 首先发现每次操作其实就是统计出增加的节点个数(原来的不会消失) 所以我们只要统计出线段树上每 ...

  4. 如何基于Winform开发框架或混合框架基础上进行项目的快速开发

    在开发项目的时候,我们为了提高速度和质量,往往不是白手起家,需要基于一定的基础上进行项目的快速开发,这样可以利用整个框架的生态基础模块,以及成熟统一的开发方式,可以极大提高我们开发的效率.本篇随笔就是 ...

  5. 虽然不抱希望但也愿.Net和Java之争暂得平息

    我在刚开始学编程的时候就经常来博客园,当时博客园基本是.Net的天下,从那时开始.Net和Java哪个好就一直在打,这些年没怎么看博客园了,回来发现到了今天居然还在争论,让我不由得想来分析一下这个问题 ...

  6. 创建SVN源库钩子

    在源库的hooks目录下面添加post-commit.bat文件,每次代码该文件会自动执行以保证同步到备份服务器 set SVN_HOME="D:\Program Files\VisualS ...

  7. Python进阶5---StringIO和BytesIO、路径操作、OS模块、shutil模块

    StringIO StringIO操作 BytesIO BytesIO操作 file-like对象 路径操作 路径操作模块 3.4版本之前:os.path模块 3.4版本开始 建议使用pathlib模 ...

  8. 会议管家——常用的JQ知识点

    一.seTimeout时间延迟 $(".ticket_one table td a").eq(0).click(function(){ editOd('57503394363048 ...

  9. PyCharm专业版的安装与破解

    1.下载pycharm:https://www.jetbrains.com/pycharm/download/#section=windows 2.这是下载好的文件,双击运行即可 3.选择安装路径 4 ...

  10. ExcelTools使用

    using NPOI.SS.Formula.Functions; using NPOI.SS.UserModel; using System; using System.Collections.Gen ...