函数库:静态库和动态库


1、函数库

函数库其实就是一些写好的函数集合,方便别人的复用。实现的封装之后,最终的目的都是给别人调用。

2、库的形式

库的形式分:动态链接库和静态链接库。

优点:

(1)库文件都是被编译好的二进制文件,别人看不到源代码,可以保持保密;(2)同时不会因为不小心被修改出现问题,便于维护。

LINUX 下的库学习:

静态链接库:.a 文件

其实就是将多函数,做编译但是不链接生成的 .o 文件,使用 ar 工具打包为 .a 的文件。编译的阶段,当调用这些库的时候,链接器就会去 .a 的库文件中拿出被调用的那个函数的 .o 文件进行链接到而执行的程序。这个过程是将库函数的 .o 的文件与主函数的文件一起打包成为一个可执行的文件,所以这个可执行的文件就会很大。加载到内存的时候,也是会占据很大的空间,生命周期是整个程序的生命周期。

缺点: 当多个可执行的文件包含了相同的库文件的时候,比如 a,b 都包含了 printf 这个库,那么内存就被会同时存在两个相同的库,多么的浪费内存啊。

动态链接库:.so 文件

动态链接库的链接方式是,在编译的阶段是不会将涉及到的库文件链接到代码中的,而是制作了一个标记;当程序运行的时候需要相应的库文件的时候,就将相应的库文件加载到内存进行使用,不用的时候就进行释放。所以使用动态链接库的时候,而到的可执行的文件会比较的小,避免了空间的浪费。

优点:动态库是在需要的时候才被进行才入到内存,所以解决了动态库的更新、部署、发布代码上面的麻烦,用户只需要加载新的动态库,做增量更新就可以了。

gcc 中编译链接默认使用的是动态链接的方式的,所以当要使用静态链接的方式的时候,就需要添加: -static

gcc a.c -o a. -static

windows:

静态库 : .lib 文件

动态库 : .dll 文件

3、制作自己的静态链接库

自己制作静态库,最主要的是生成自己的 .a 文件和 .h 文件。

(1)制作自己库函数原材料

test.c 就是我们制作库函数材料:

#include<stdio.h>
int fun1(int a,int b)
{
    return a + b;
}
int fun2(int a, int b)
{
    return a * b;
}

定义了两个函数的实现方式。

(2)生成头文件

上一步实现了 test.c 的实现的方式,所以我们必须有与库材料同名的头文件。

test.h

int fun1(int a,int b);
int fun2(int a,int b);

头文件其实就是将实现的材料的函数原型进行声明。记得是原型。

(3)生成库文件

Makefile:

all:
    gcc test.c -o test.o -c
    ar -rc libtest.a test.o

将 test.c 生成为 .o 的文件,这里使用了: -c 进行了指定为只是进行编译,但是没有进行链接。记住 c 是小写的哦。

使用 ar 打包工具生成 libtest.a。这里的库的名字不能是随意进行取名的,因为文件是 test.o 的文件,所以库的名字只能是 libtest.a,也就是lib + 文件的名字。


(4)使用自己的静态链接库

上面的步骤已经得到了我们需要的 .h 和 .a 的文件。

自己的代码:

#include<stdio.h>
#include"test.h"
int main(int argc, char *argv[])
{
    int i;
    i = fun1(1, 2);
    printf("i = %d\n", i);
    i = fun2(3, 4);
    printf("i = %d\n", i);
}

编译的方式:

gcc testlib.c -o testlib -L /home/qxj511/python -ltest

-L : 指定库文件的路径,这里指定的是绝对的路径,当前路径的话,可以用电进行表示。

-ltest : 执行库的名字。上面我们生成的库的名字是 libtest.a,而我们这里是使用了小写的 l 代表了 lib,所以就可以使用 libtest 去代替。

(5)nm 命令

nm 命令是可以查看一个动态库和静态库里面的符号信息。、

nm libtest.a
输出的信息:
test.o:
00000000 T fun1
0000000d T fun2

可见库里面只是包含了 一个 test.o(一般的库文件都是包含大量的 .o 的文件),而 test.o 里面只是包含了两个 函数。

4、制作自己的动态链接库

制作的材料使用上面的 test.c,头文件的话也是 test.h,这里都不做修改。

(3)生成动态链接库

Makefile:

gcc test.c -o test.o -c -fPIC
gcc -o libtest.so test.o -shared

-fPIC :执行生成的 .o 的文件是位置无关码的。

-share : 以生成动态链接库

这样就得到了 .h 和 .so库文件了。

(4)使用自己的动态链接库

gcc testlib.c -o testlib -L /home/qxj511/python -ltest

编译一次性成功,但是运行的时候确实报错了。原因是:动态链接库是实现动态加载的,当需要调用相关库的时候,去加载相应的库,而默认加载动态库的路径是系统的固定路径,所以解决的办法:

方法一:将自己的动态库放到系统的目录: /usr/lib/ 目录里面。

方法二:添加 LD_LIBRARY_PATH。 LD_LIBRARY_PATH 是系统加载路的路径,操作系统加载固定目录的时候,先回去 LD_LIBRARY_PATH 去寻找相应的库文件,当没有找到的时候采取固定的目录: /usr/lib/ 下寻找。、

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/qxj511/python

通过 export 命令添加了库寻找的路径。

(5)ldd 命令

ldd 命令的作用是查看文件依赖哪些的共享库,并且查看这些库是否可以被找到,能被解析。

[email protected]:~/python# ldd testlib
    linux-gate.so.1 =>  (0xb76fe000)
    libtest.so (0xb76f9000)
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb753c000)
    /lib/ld-linux.so.2 (0xb76ff000)

可见,我们的可执行的文件是依赖于四个库。上面的意思是这四个库都可以被找到,都是指向于数字地址,。当没有找到这些库的时候,就会出现: n、

not found。

时间: 2024-08-05 15:16:40

函数库:静态库和动态库的相关文章

Linux下c函数dlopen实现加载动态库so文件代码举例

dlopen()是一个强大的库函数.该函数将打开一个新库,并把它装入内存.该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的.这种机制使得在系统中添加或者删除一个模块时,都不需要重新编译了.可以在自己的程序中使用 dlopen().dlopen() 在 dlfcn.h 中定义,并在 dl 库中实现.它需要两个参数:一个文件名和一个标志.文件名就是一个动态库so文件,标志指明是否立刻计算库的依赖性.如果设置为 RTLD_NOW 的话,则立刻计算:如果设置的是 RTLD_LAZY,则在需要

动态库(非MFC动态库)

一.C语言动态库 1.创建C语言动态库,并封装函数: 1)创建新工程:Win32 Dynamic-Link Library 2)添加SourceFiles文件:Cdll.c Cdll.c中的内容: //创建C的动态库 //_declspec(dllexport)声明导出 _declspec(dllexport)int Cdll_add(int add1,int add2){     return add1+add2; } _declspec(dllexport)int Cdll_sub(int 

C/C++ (函数、变量和类)动态库的创建、导出和使用(图文+示例代码)

 一 Windows库 1引入库的原因: a.项目的复杂程度大 b.提高代码的利益利用率 2库的分类 2.1静态库: *.lib,不能被加载的程序,可以理解为目标程序的归档. 2.2动态库:*.dll,可以被应用程序加载的程序. 二 动态库 1动态库优点 1.1可以提供模块化的方式,方便协调开发(对于大项目,每个人写的东西编译为动态库,直接链接即可) 1.2对源代码保护 1.3减小可执行文件大小 1.4提高代码重用率 2动态库的基本使用方法 2.1动态库的创建 2.2加载动态库 2.3获取并

Android导入第三方静态库.a编译成动态库.so

http://ikinglai.blog.51cto.com/6220785/1324985 在Android开发的时候,经常会使用到用c或c++编写的第三方的静态库.如果有源码的话,可以直接跟你自己的代码一去编译成动态库so,但是如果没有源码的话,你就必须在自己的动态库so里面将别人生成好的静态库导入进来一起编译了.我在编译的时候遇到了不少问题,我觉得有必要进行总结一下. 下面我以一个简单的实际例子来讲解如何在动态库中导入静态库. 静态库中的源代码有两个文件:static.h, static.

MFC的亚博静态库.lib、体育动态库.dll以及Unicode库示例

MFC亚博静态库使用下列体育命名约定: uAFXcWd.LIB . 库命名约定的说明符如下: 说明符 值和含义u (n) ANSI 或 (u)Unicodec 创建的计划类型:c=alld d=debug版本; release版本略去说明符默认值为生成用于 Intel 平台的调试版本 windows ANSI 应用程序的静态库:NAFXCWD.Lib. 下表列出的所有库是在 \ atlmfc \ lib 目录中包含预生成的静态库. 静态链接库命名约定: 库 说明NAFXCW.LIB MFC 静态

Makefile 编译动态库文件及链接动态库

本文为原创文章,转载请指明该文链接 文件目录结构如下 1 dynamiclibapp.c 2 Makefile 3 comm/inc/apue.h 4 comm/errorhandle.c 5 dynamiclib/Makefile 6 dynamiclib/dynamiclib_add.c 7 dynamiclib/dynamiclib_mul.c 8 dynamiclib/inc/dynamiclibs.h 9 dynamiclib/libs/ 1. dynamiclib目录 dynamic

9.20 windows静态库和动态库的使用 函数可变参 递归使用 多线程查找

指针内存面试题:                           对整个数组取地址+1前进了整个数组.再强转成double*  根据double*步长再减去1 #include <stdio.h> int main() { double db[5] = {1.0,2.0,3.0,4.0,5.0}; printf("%f\n", *((double *)(&db + 1) - 1)); // 结果输出5.0 return 0; } #include <std

静态库和动态库的分析

本质上来说库是一种可执行代码的二进制形式. linux下的库有两种:静态库和共享库(动态库) 静态库在程序编译时会被连接到目标代码中:程序运行时将不再需要该静态库,因此体积较大. 优点:程序运行时将不再需要该静态库 缺点:可执行文件的体积较大. 相同的库可能会需要被多次加载. 静态库: libxxxxx.a 动态库:动态库在程序编译时并不会被连接到目标代码中, 优点: 在程序运行时动态库才会被载入内存,因此代码体积较小. 缺点: 因此在程序运行时还需要动态库存在. 静态库的制作:将功能函数编译成

动态库和静态库

 1.静态库不需要main函数,要想生成lib,要修改属性à常规à配置类型à改成dll 2.静态库中的头文件只是说明,是给程序员看的,其实lib里面已经有了接口. 3.链接lib的时候程序的体积就变大了. 4.静态库更新的时候,需要重新生成,然后调用 5.动态库调用就不用重新生成. 6.动态库的调用代码:(使用的是HMODULELoadLibraryA的方式进行调用) 接口 7.编写的动态库如下: #include<stdio.h> #include<stdlib.h> #in