文档章节

创建C语言静态库与动态库

大道无名
 大道无名
发布于 2016/10/24 21:39
字数 1787
阅读 466
收藏 1

    “程序库”就是包含了一些同音函数的数据和二进制可执行机器码的文件。这些文件是目标文件的一种,其不能单独执行。但是如果将其与其他的可执行代码结合起来就可以执行。这些目标文件通常可以完成同一类功能,他们可以作为其他执行程序的一部分来执行。由于库的存在,使得用户编写的程序模块化更强,从而可以加强程序的再编译,提高代码的复用性。

从链接方式上,程序库可分为静态库和动态库(共享库)两种:

  • 静态库:是在执行程序运行前就已经加入到执行码中,成为执行程序的一部分来执行。
  • 动态库:是在执行程序启动是加载到执行程序中,可以被多个执行程序共享使用。

一、静态库

1.静态库的概念

静态库是一些目标代码的集合。linux环境下的静态库目标文件一般以.a作为扩展名。Linux环境下使用ar命令创建一个静态库。静态库的优点在于使用简单,编译快速,静态库在应用程序生成时,已经编译成为可重定位的目标文件,因此可不必再编译。

由于静态库在编译时已经复制到可执行代码段中,所以不需要像使用动态库那样在程序加载时再次链接。

2.创建静态库

创建一个四则运算的静态库:

(1)四则运算的代码为:

/* 计算加法的函数 */
int add(int a, int b)
{
  return a + b;
}

/* 计算减法的运算 */
int sub(int a, int b)
{
  return a - b;
}

/* 计算乘法的运算 */
int mul(int a, int b)
{
  return a * b;
}

/* 计算除法的运算 */
int div(int a, int b)
{
  return a / b; 
}

(2)在shell中编译源文件,生成一个可重定位的目标文件:

gcc -c static_lib.c

生成的目标文件为:

static_lib.o

(3)Linux下使用工具ar创建一个静态库,或者将目标文件加入到一个已经存在的静态库中,使用方法如下:

ar rcs 静态库名 目标文件1 目标文件2...目标文件n

该命令将目标文件1~n加入到指定的静态库中。如果该静态库不存在,则创建静态库文件。其中ar工具的参数rcs起到了重要的作用。这三个参数分别表示:

  • 参数r:把列表中的目标文件加入到静态库中
  • 参数c:若指定的静态库不存在,则创建该库文件
  • 参数s:更新静态库文件的索引,是指包含新加入的目标文件的内容

现在使用刚生成的.o文件创建一个静态库:

ar rcs libstatic_lib.a static_lib.o

这样就生成了一个新的静态库:

libstatic_lib.a

3.使用静态库

静态库创建成功后,需要链接到应用程序中使用。应用程序可以引用该库中的函数或者全局变量。为了是应用程序可以正确引用该库中的全局符号,需要制作一个包含该静态库中全局符号声明的头文件,这个头文件可以包含在应用程序的头文件中,这样就可以使用静态库中的全局符号了。

#include <stdio.h>
#include "static_lib.h"

int main(void)
{
  int a, b;
  printf("please input a and b\n");
  scanf("%d %d", &a, &b);
  printf("the add : %d\n", add(a, b));
  printf("the sub : %d\n", sub(a, b));
  printf("the mul : %d\n", mul(a, b));
  printf("the div : %d\n", div(a, b));
  return 0;
}

使用-l选项来指定静态库,-L参数来指定库文件的搜索路径。-l和-L之后都栉jie风沐雨带参数而不跟空格,所以用一下命令编译:

gcc -L/home/daowm/WorkSpace/C/linux/ch7 static_main.c -lstatic_lib -o static_main

或者使用 "." 表示当前目录:

gcc -L. static_main.c -lstatic_lib -o static_main

注意:-l是链接器选项,一定要放在被编译的源文件之后,即上面的static_main.c之后,若放在前面则会链接失败。

gcc也支持使用-static选项对静态库链接:

gcc static_main.c -static ./libstatic_lib.a -o static_main

以上三种方法都可以。

运行程序如下:

二、动态库

1.动态库的概念

动态库又称为共享库或者动态链接库,现代程序中大量地使用动态链接库,如windows下的dll文件和linux下的so文件,动态库是在程序启动时被装载的。

当一个引用程序装载了一个动态库后,其他应用程序仍可以装载同一个动态库,这个被多个进程同时使用的动态库在内存中只有一个副本。动态库的优点很多:

  • 是代码
  • 便于程序发布
  • 易于模块更新,更新库并不影响程序使用旧的版本
  • 在执行特定程序时,可以覆盖整个库或者更新库中的特定函数

2.创建动态库

这里使用上面的代码来演示

(1)四则运算代码

//static_lib.c
/* 计算加法的函数 */
int add(int a, int b)
{
  return a + b;
}

/* 计算减法的运算 */
int sub(int a, int b)
{
  return a - b;
}

/* 计算乘法的运算 */
int mul(int a, int b)
{
  return a * b;
}

/* 计算除法的运算 */
int div(int a, int b)
{
  return a / b; 
}

(2)Linux下使用gcc创建一个动态库。由于动态库可以被多个进程共享加载,所以需要生成位置无关的目标文件。这时需要使用gcc编译器的-fPIC选项,该选项用于生成位置无关的代码。除了需要使用-fPIC选项外,还需要使用-shared选项,该选项将位置无关的代码制作为动态库。

gcc -shared -fPIC -o shared_lib.so static_lib.c 

这时一个新的动态库就创建成功了。之后用户可以在自己的应用程序中引用该库中的函数,在程序加载的时候链接该库就可以了。

3.使用动态库

动态库创建成功后,应用程序可以引用该库中的函数或者全局变量。同样在.h文件包含该动态库中的全局符号:

//shared_lib.h

extern int add(int a, int b);  //加法函数的声明
extern int sub(int a, int b);  //减法函数的声明
extern int mul(int a, int b);  //乘法函数的声明
extern int div(int a, int b);  //除法函数的声明

编写程序:

//shared_main.c

#include <stdio.h>
#include "shared_lib.h"

int main(void)
{
  int a, b;
  printf("please input a and b\n");
  scanf("%d %d", &a, &b);
  printf("the add : %d\n", add(a, b));
  printf("the sub : %d\n", sub(a, b));
  printf("the mul : %d\n", mul(a, b));
  printf("the div : %d\n", div(a, b));
  return 0;
}

使用动态库编译生成可执行程序:

gcc shared_main.c ./shared_lib.so -o shared_main

运行结果同上。

同时,另外一个程序也可以使用该动态库,因为动态库是共享的。

 

© 著作权归作者所有

大道无名
粉丝 29
博文 161
码字总数 96019
作品 0
宣城
程序员
私信 提问
C语言库的制作

制作C语言库 编写头文件,在文件内声明要用到的函数, libh.h #include <stdio.h> // 两数相加 int add(int a, int b); // 绝对值 int mabs(int a); 编写c语言库源码文件, 在文件内定义之前...

首席撸起水泡
2016/01/08
94
0
Android 之 JNI 开发 详解 - NDK从入门到精通

NDK项目源码地址 : -- 第一个JNI示例程序下载 : GitHub - https://github.com/han1202012/NDKHelloworld.git 一. JNI介绍 1. JNI引入 JNI概念 : Java本地接口, Java Native Interface, 它是一......

SuShine
2016/11/04
665
0
Android studio JNI开发的三种方式

Android studio JNI开发的三种方式。 第一种 第一步: 创建natice本地方法 第二步: 在工程App模块目录下创建jni文件夹 第三步: 在jin文件夹中创建.c结尾的c文件,编写c代码,在c语言中定义在Jav...

Android
2017/12/19
0
0
Linux系统中“动态库”和“静态库”那点事儿-【经典好文】

原文链接:http://blog.csdn.net/u010977122/article/details/52958330 今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻。在这之前,我们需要了解一下源代码到可执行...

1清风揽月1
2017/06/14
0
0
gcc 使用中常用的参数及命令

执行过程 虽然我们称Gcc是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤∶预处理(也 称预编译,Preprocessing)、编译(...

Dicky
2012/10/20
165
0

没有更多内容

加载失败,请刷新页面

加载更多

nginx主备模式笔记

(1)两台服务器 192.168.17.129 和 192.168.17.131 (2)在两台服务器安装 keepalived 安装 keepalived (1)使用 yum 命令进行安装 yum install keepalived –y (2)安装之后,在 etc 里面...

行者终成事
今天
4
0
004-Docker镜像

Docker镜像 一个通用的私有仓库,可以提升效率 Docker镜像构建分为两种,一种是手动构建,一种是Dockerfile(自动构建) 基于centos镜像构建手动制作nginx镜像 docker run --name testdocker -...

伟大源于勇敢的开始
今天
5
0
OSChina 周一乱弹 —— 我就加班,不去世不休息

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 :《For Forever》90后那些小鲜肉歌手中,好像只有花花的歌能吸引我,这小家伙对音乐的感觉真是天才一般!#今日歌曲推荐# 《For F...

小小编辑
今天
9
1
【领会要领】web前端-轻量级框架应用(jQuery基础)

作者 | Jeskson 来源 | 达达前端小酒馆 jquery的安装和语法,jquery的多种选择器,dom操作和jquery事件。 jQuery框架,简介,优势,安装,语法,jQuery选择器,id选择器,类选择器,标记选择...

达达前端小酒馆
今天
6
0
MySQL 常用命令

无须死记硬背,直接 copy 就好。 1. 查看目前 mysql 用户 select user,host,password from mysql.user; 2. 修改 root 密码(使用内置函数修改) set password for root@localhost=password('y......

HuaiAnGG
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部