C語言函數篇(五)靜態庫和動態庫的創建和使用


使用庫函數是源碼的一種保護???  <我猜的.>

庫函數其實不是新鮮的東西,我們一直都在用,比如C庫.

我們執行pringf() 這個函數的時候,就是調用C庫的函數.

 

下面記錄靜態庫和動態庫的生成和使用.

 

靜態庫:libxxx.a

動態庫:libxxx.so

 

靜態庫: 在程序編譯的時候,將庫編譯進可執行程序中, 運行的時候不需要外部函數庫

動態庫: 在程序運行的時候,將庫加載到程序中,運行的時候需要外部函數庫

函數庫的目錄有 /lib /usr/lib自定義

 

一. 靜態庫的生成和使用

下面通過一個簡單的小栗子來介紹庫函數怎么生成和使用.

1.庫函數的源碼 hello.c

#include "stdio.h"

int hello(void){ printf("hello lib");   return 0; }

2. 庫函數的頭文件 hello.h

#ifndef __HELLO_H #define __HELLO_H

int hello(void); #endif

庫文件的頭文件是庫文件的目錄,因為庫文件是保護的,看不到里面的源碼,所以把函數接口通過頭文件來讓人調用 .

這樣就實現了接口,也保護了源碼

 

3.編譯靜態庫函數

3.1 將 hello.c 編譯成目標文件 生成  hello.o文件

gcc -c hello.c

3.2 將.o文件打包成靜態庫 生成 libhello.a庫文件

ar -cr libhello.a hello.o

 

4 使用靜態庫,因為靜態庫是在編譯的時候一起打包進程序的,所以如果編譯的時候沒有靜態庫文件,則無法編譯

4.1 main.c 寫一個main函數來調用庫函數

#include "hello.h"    //引入庫函數的頭文件,這樣才能找到函數聲明

int main{ hello(); //調用庫函數
 }

正常編譯的時候是沒辦法通過的. 因為編譯器找不到 hello() 的實現代碼. 如圖:

所以在編譯的時候要加入庫引用

gcc -c main -L. -lhello -o a.out  

-L<路徑> 引用自定義庫的路徑,如果調用系統庫就不用-L  '.'表示當前文件夾 

-lxxxx 這里libhello.a 只要寫hello 就可以   //小寫的L

4.2 直接可以執行,因為庫函數已經被編譯進去了

 

二.動態庫的編譯及使用

同樣的hello.c 源碼

1.生成.o文件

gcc -c -fpic hello.c //如果這里沒有加-fpic 下一步就會提示你重新用 -fpic編譯

2. 編譯成動態庫

gcc -shared -fpic -o libhello.so hello.o

-shared 是生成動態庫

-fpic 生成位置無關代碼,默認加

 

3. 使用動態庫 和靜態庫一樣

gcc main.c -L. -lhello -o a.out

 

4. 執行 用動態庫編譯的程序沒辦法直接執行

在讀取共享庫libhello.so的時候出錯,沒有找到該文件

因為動態庫程序會默認在 /lib  或者 /usr/lib的路徑下尋找, 所以

 

 

解決的辦法有3個:

1. 將.so 文件拷貝到 /usr/lib/文件夾下面

2.添加PATH環境變量

export LD_LIBRARY_PATH=<動態庫所在的絕對路徑>

3.修改配置腳本

將動態庫所在的路徑加到  /etc/ld.so.conf 文件里

vim /etc/ld.so.conf

添加后刷新

/sbin/ldconfig

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM