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

一、介绍

在软件编程中,通常会把功能或接口函数封装成库的形式,供给其它模块或第三方使用。在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 $@ main.c $(LIBRARY)

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

libmath_method.a: math_method.o
        ar cr $@ $^
        ranlib $@

libmath_method.so: math_method.o
        $(CC) -shared -o $@ $^

.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


 

猜你喜欢

转载自blog.csdn.net/szkbsgy/article/details/81541975