欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux 动态库、静态库的生成、使用和优缺点分析

程序员文章站 2022-06-03 13:50:45
...

一、介绍

在软件编程中,通常会把功能或接口函数封装成库的形式,供给其它模块或第三方使用。在linux系统中存在动态库和静态库两种形式。

静态库:以libxxx.a形式命名,编译程序时,会将静态库数据编译进可执行程序中。

动态库:以libxxx.so形式命名,编译程序时,不会被编译进可执行程序中,而在程序运行时,动态的加载该动态库

二、生成(以libmath_method.a/so为例)

2.1 静态库的生成

gcc -c math_method.c
ar cr libmath_method.a math_method.o
ranlib libmath_method.a

查看库中包含的文件:

ar -t libmath_method.a
math_method.o

2.2 动态库的生成

gcc -fPIC -c math_method.c
gcc -shared -o libmath_method.so math_method.o

三、编译链接

-L  指定搜寻库的目录
      如指定当前目录 gcc -L .
-l  指定要链接的库的名称
      加入库的名称是libmath_method.a(.so),则gcc -lmath_method

链接时,如果动态库和静态库同时存在,优先使用动态库。也可以通过以下的参数指定动态或静态库

-Wl,-dn :指定动态库

-Wl,-dy:指定动态库

四、查看程序链接的动态库库

$ ldd a.out
        linux-vdso.so.1 =>  (0x00007ffff47cb000)
        libmath_method.so => not found
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd659906000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fd659cdb000)


五、程序运行
4.1 静态库程序的运行
./a.out

4.2 动态库版本程序的运行

./a.out: error while loading shared libraries: libmath_method.so: cannot open shared object file: No such file or directory

出现上述错误是因为找不到动态库,有以下两种方式可以解决:
一、可以把当前路径加入 /etc/ld.so.conf中然后运行ldconfig

二、把当前路径加入环境变量LD_LIBRARY_PATH中,仅在当前环境有效
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

六、静态库和动态库优缺点

1. 静态库程序会将函数库编译时程序,因此程序较大, 而动态库程序较小

2. 由于静态库在编译时已经将函数库编译进程序中,因此运行时不需要库的支持;而动态库程序在运行时必须提供相应的库程序

3. 库文件变化时,静态库程序需要重新编译; 而动态库只需要替换运行环境中的库文件

4. 多个程序使用库文件时,静态库需要每个程序都编译时各自的程序中,而动态库只需要在运行环境共享一份即可

七、源码

Makefile:

CC=gcc
LIBRARY=-L. -Wl,-dy -lmath_method -Wl,-dy -lgcc_s

TARGET=a.out

$(TARGET): libmath_method.a libmath_method.so
        gcc -o [email protected] main.c $(LIBRARY)

math_method.o: math_method.c
        $(CC) -fPIC -c math_method.c

libmath_method.a: math_method.o
        ar cr [email protected] $^
        ranlib [email protected]

libmath_method.so: math_method.o
        $(CC) -shared -o [email protected] $^

.PHONY:
clean:
        -rm -rf *.o *.a
        -rm $(TARGET)

main.c:

#include <stdio.h>

#include "math_method.h"

int main(int arc, char *argv[])
{
    printf("hello world\n");

    printf("%d + %d = %d\n", 1, 9, math_add(1, 9));

    return 0;
}

math_method.c:

#include <stdio.h>


int math_add(int a, int b)
{
    return a + b;
}

int math_sub(int a, int b)
{
    return a - b;
}

math_method.h:

#ifndef __MATH_METHOD_H__
#define __MATH_METHOD_H__


int math_add(int a, int b);

int math_sub(int a, int b);

#endif