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


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章