相关阅读: 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. 英语进阶系列-A05-英语升级练习三

    古诗背诵 要求:认真背诵和朗读,然后翻译成现代文,并绘制图像描述图中的意向,时间限制到10 minutes.另外,从中找出英文单词,并记录. 例如:慈母 = kind mother,手 = hand, ...

  2. django自定义分页器

    一 django 的分页器 1 批量创建数据 批量导入数据: Booklist=[] for i in range(100): Booklist.append(Book(title="boo ...

  3. c++11の简单线程管理

    1.简单的例子 #include "stdafx.h" #include <iostream> #include <thread> void functio ...

  4. Text Mining and Analytics WEEK1

    第一周目标 解释自然语言处理中的一些基本概念 解释不同的方式来表示文本数据 解释的两种基本的词联想以及如何从文本数据挖掘聚合关系 尝试回答以下问题 为了理解一个自然语言句子,计算机必须做些什么? 什么 ...

  5. CentOS-常用安装

    JDK安装 1.检查jdk版本:java -version 2.检查jdk安装包:rpm -qa|grep java 3.将要安装的jdk的tar.gz包拖入,CRT快捷键ALT+P 4.解压到指定目 ...

  6. EF 6.x和EF Core实现返回dynamic类型

    前言 未曾想需要直接返回dynamic,多次尝试未能实现,最终还是在stackoverflow上找到了解决方案,特此备忘录. public static dynamic SqlQuery(this D ...

  7. IPv6绝不仅仅是对IPv4地址长度的增加

    众所周知,IPv6 IP地址长度是IPv4 IP地址长度的四倍,是解决IPv4公共网址资源枯竭的最佳技术.的确,IETF在制定IPv6标准时也是基于这一因素考虑的.当时正是90年代初,Web开始出现, ...

  8. adoop(四)HDFS集群详解

    阅读目录(Content) 一.HDFS概述 1.1.HDFS概述 1.2.HDFS的概念和特性 1.3.HDFS的局限性 1.4.HDFS保证可靠性的措施 二.HDFS基本概念 2.1.HDFS主从 ...

  9. VUE浏览器储存封装

    import {isFunction, extend} from 'lodash' const _originStorage = function () { var pluses = /\+/g fu ...

  10. RCNN算法的tensorflow实现

    RCNN算法的tensorflow实现 转载自:https://blog.csdn.net/MyJournal/article/details/77841348?locationNum=9&f ...