編寫簡單的函數並將其打包成靜/動態庫

寫一個數學庫

靜態庫與動態庫

靜態庫(.a):程序在編譯鏈接的時候把庫的代碼鏈接到可執行文件中。程序運行的時候將不再需要靜態庫。
動態庫(.so):程序在運行的時候纔去鏈接動態庫的代碼,多個程序共享使用庫的代碼。
一個與動態庫鏈接的可執行文件僅僅包含它用到的函數入口地址的一個表,而不是外部函數所在目標文件的整個機器碼。
-在可執行文件開始運行前,外部函數的機器碼由操作系統從磁盤上的該動態庫中複製到內存中,這個過程稱爲動態鏈接。
動態庫可以在多個程序間共享,所以動態鏈接使得可執行文件更小,節省了磁盤空間。操作系統採用虛擬內存機制允許物理內存中的一份動態庫被要用到該庫的所有進程共用,節省了內存和磁盤空間。

實現加、減法

靜態庫

1.首先touch 4個文件:add.c、add.h、sub.c、sub.h
兩個 “.c”文件提供方法實現,兩個“.h”文件提供方法聲明。
注:庫裏面不能有main()函數,main()函數是程序的入口。

編寫“.h”文件

#pragma once
#include<stdio.h>
int myadd(int x,int y);
#pragma once
#include<stdio.h>
int mysub(int x,int y);

編寫“.c”文件

#include"add.h"
int myadd(int x,int y)
{
    return x+y;
}
#include"sub.h"
int mysub(int x,int y)
{
    return x-y;
}

靜態庫是鏈接的時候被引入的,我們自己寫的程序什麼時候鏈接是被引入的??我們的文件經過預處理、編譯、彙編、鏈接,在鏈接之前的狀態彙編之後生成一個文件叫”.o”文件,叫做目標文件。
所謂的靜態庫,其實是把這些”.o”文件打包在一起所以前提條件我們要有兩個”.o”文件。

這裏寫圖片描述

接下來將兩個”.o”文件打包生成靜態庫,用到的工具叫做“ar”
ar是gnu歸檔工具,rc表示(replace and create)

這裏寫圖片描述

重新創建一個目錄test。
我們要用靜態庫不僅需要把庫拿進來,還需要把頭文件拿進來。

這裏寫圖片描述

頭文件裏只有函數聲明沒有函數實現所以不怕給別人。

編寫main.c文件進行測試

#include<stdio.h>
#include"add.h"
#include"sub.h"
int main()
{
    int x = 100;
    int y = 30;
    int z = mysub(x,y);
    int f = myadd(x,y);
    printf("%d %d\n",z,f);
    return 0;
}

直接進行編譯,發現報了一個錯誤

這裏寫圖片描述

所以要在gcc後加選項
“-L”表示指定目錄查找
“-L .”表示在當前的目錄下查找庫

這裏寫圖片描述

發現還是沒找到。原因是什麼呢??
當前目錄雖然現在只有一個庫,但是當前目錄也可以放100個庫,只說明了庫的路徑在那個目錄下,卻沒有說明要鏈接哪個庫。
所以還要再加一個選項”-l(小L)”表明我們要鏈接哪個庫

編譯成功後會生成一個main,然後運行就得到了結果

這裏寫圖片描述

所以以後寫好程序要給別人打個庫,要給他所有的頭文件和”.a”文件

動態庫

生成動態庫:
fPIC:產生位置無關碼(這個庫將來裏面的地址各方面事宜加載到哪裏都可以運行)
再創建一個動態庫目錄將靜態庫中的”.h”文件和”.c”文件拷貝進來,接下來生成與位置無關的,此時生成兩個”.o”文件
這裏寫圖片描述
接下來把兩個”.o”文件打包成共享庫,但還需要使用一個命令
shared:表示生成共享庫格式
這裏寫圖片描述
再創建一個test目錄用於測試將”.h”文件和動態庫拷貝進來
這裏寫圖片描述
將靜態庫的main.c也拷貝進來

直接進行編譯會出現錯誤:鏈接時找不到
這裏寫圖片描述
採用與靜態庫同樣的方法進行處理
這裏寫圖片描述
此時能找到庫,生成了可執行程序

下面運行程序,報錯沒有這個文件
這裏寫圖片描述
因爲沒有在當前目錄下找。
靜態庫:程序一旦編譯鏈接好就不用再關心靜態庫了,編譯完成後刪掉靜態庫,程序也可以正常運行。可是動態庫則不是,程序編譯鏈接好仍然需要動態庫,接下來是加載。不僅要編譯鏈接時找到動態庫,運行時也要找到。所以有一個環境變量LD_LIBRARY_PATH,該環境變量是系統查找加載動態庫時的路徑。ldd用來記錄一個應用程序所依賴的動態庫。
這裏寫圖片描述
更改環境變量,就可以找到動態庫
這裏寫圖片描述
運行成功
這裏寫圖片描述

小結:

要使用動態庫有以下三種方法:
1.拷貝”.so”文件到系統共享庫路徑下,一般指/usr/lib
2.更改LD_LIBRARY_PATH
3.ldconfig配置/etc/ld.so.conf.d/,ldconfig更新

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