嵌入式 Linux C語言(十一)——靜態庫函數和動態庫函數
一、靜態鏈接庫
靜態鏈接庫是obj文件的一個集合,通常靜態鏈接庫以".a"爲後綴,名字格式一般爲libxxx.a,由程序ar生成。靜態鏈接庫是在程序編譯過程中鏈接的,已經將調用的相關函數拷貝到程序內部,程序運行時和靜態鏈接庫已經沒有任何關係。
1、靜態鏈接庫的創建
A、編寫源碼庫文件
源碼庫文件一般包含.c和.h文件,
hello.c文件:
#include <stdio.h>
void display(void)
{
printf("hello world\n");
}
hello.h文件:
#ifndef __HELLO_H
#define __HELLO_H
void display(void);
#endif
B、編譯源碼庫文件
gcc -o hello.o -c hello.c
生成hello.o目標文件
C、將目標文件歸檔生成靜態鏈接庫文件
ar -cr libhello.a hello.o
D、發佈靜態鏈接庫
一般來說,靜態鏈接庫需要發佈libxxx.a和.h文件,.h文件可以讓第三方開發者瞭解靜態鏈接庫中的各函數的功能和函數聲明,libxxx.a文件是第三方開發者在調用靜態鏈接庫中的函數後在編譯鏈接階段鏈接的庫。
2、靜態鏈接庫的使用
A、查閱靜態鏈接庫的.h文件
獲取發佈的靜態鏈接庫後,查看.h文件,看靜態鏈接庫的各個函數功能和函數聲明。
B、使用靜態鏈接庫的某個函數
使用靜態鏈接庫時需要聲明靜態鏈接庫的.h文件
#include "hello.h"
int main(int argc, char**argv)
{
display();
return 0;
}
C、編譯工程文件
編譯工程文件時,需要在編譯鏈接時添加相關選項:
-Lpath:表示在path目錄中搜索庫文件,如-L.則表示在當前目錄。
-lxxx:表示要鏈接的靜態鏈接庫爲libxxx.a
-static:表示將所有鏈接的庫靜態加載
gcc -o main main.c -L. -lhello
二、動態鏈接庫
動態鏈接庫是程序運行時加載的庫,當動態鏈接庫正確安裝後,所有的程序都可以使用動態庫來運行程序。動態鏈接庫是目標文件的集合,目標文件在動態鏈接庫中的組織方式是按照特殊方式形成的。庫中函數和變量的地址是相對地址,不是絕對地址,其真實地址在調用動態庫的程序加載時形成。
1、動態鏈接庫的創建
A、編寫源碼庫文件
源碼庫文件一般包含.c和.h文件,
hello.c文件:
#include <stdio.h>
void display(void)
{
printf("hello world\n");
}
hello.h文件:
#ifndef __HELLO_H
#define __HELLO_H
void display(void);
#endif
B、編譯源碼庫文件
gcc -fPIC -c hello.c -o hello.o
生成目標文件hello.o
-fPIC選項的作用是使得gcc生成的代碼是位置無關的
C、生成動態鏈接庫
gcc -shared -o libhello.so hello.o
生成動態鏈接庫libhello.so文件
-shared選項告訴編譯器生成一個動態鏈接庫
2、動態鏈接庫的使用
A、查閱動態鏈接庫的.h文件
獲取發佈的動態鏈接庫後,查看.h文件,看動態鏈接庫的各個函數功能和函數聲明。
B、使用動態鏈接庫的某個函數
使用動態鏈接庫時需要聲明動態鏈接庫的.h文件
#include "hello.h"
int main(int argc, char**argv)
{
display();
return 0;
}
C、編譯工程文件
編譯工程文件時,需要在編譯鏈接時添加相關選項:
-Lpath:表示在path目錄中搜索庫文件,如-L.則表示在當前目錄。
-lxxx:表示要鏈接的動態鏈接庫爲libxxx.so
gcc -o main main.c -L. -lhello
D、將動態鏈接庫文件註冊到系統環境變量中的庫加載路徑
方法一:將動態鏈接庫文件拷貝到系統環境變量中的庫加載路徑中的某個目錄
cp libhello.so /usr/lib
方法二:將當前目錄添加爲統環境變量中的庫加載路徑
把當前工作目錄加入動態鏈接庫的搜索路徑配置文件/etc/ld.so.conf中。
如果沒有以上操作,運行時程序將會報錯:
error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory
程序運行時將會到相應目錄下加載動態鏈接庫中的函數執行。
E、程序運行時的庫依賴
ldd命令可以查詢程序運行時需要的依賴庫
ldd main
linux-vdso.so.1 => (0x00007fff265d8000)
libhello.so => /usr/lib/libhello.so (0x00007f15d8af1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f15d8733000)
/lib64/ld-linux-x86-64.so.2 (0x00007f15d8d05000)