c的靜態庫和動態庫

来源:http://www.cnblogs.com/csun/archive/2016/05/25/5526043.html
-Advertisement-
Play Games

1(1)庫文件:靜態庫文件 和 共用庫文件(2)比較a.靜態庫文件: 使用靜態庫文件時,直接把代碼/指令複製到目標文件中 目標文件會顯得比較龐大,修改和維護都不方便 可以脫離靜態庫文件,效率比較高 b.共用庫文件: 使用共用庫時,將代碼/指令所對應的地址複製到目標文件 目標文件會比較小,修改和維護比 ...


1(1)庫文件:靜態庫文件 和 共用庫文件
(2)比較
a.靜態庫文件:
使用靜態庫文件時,直接把代碼/指令複製到目標文件中
目標文件會顯得比較龐大,修改和維護都不方便
可以脫離靜態庫文件,效率比較高

b.共用庫文件:
使用共用庫時,將代碼/指令所對應的地址複製到目標文件
目標文件會比較小,修改和維護比較方便
不可以脫離共用庫文件,效率比較低
(3)基本命令
ldd a.out => 查看文件a.out所依賴的庫文件
gcc/cc -static xxx.c => 要求按照靜態庫方式編譯鏈接,得到的可執行文件會比較大

2 靜態庫文件的生成和使用
(1)靜態庫文件的生成步驟
a.編寫源代碼xxx.c,如:vi adder.c
b.只編譯不鏈接生成.o的目標文件
gcc/cc -c adder.c
c.使用命令ar -r/*插入*/ lib庫名.a xxx.o 生成靜態庫
ar -r libadder.a adder.o
註意:
a.lib庫名.a 叫做靜態庫文件名,與庫名不同,註意區分
b.靜態庫文件的命名規則一般為lib開頭,.a為尾碼,中間的庫名自定義即可

(2)靜態庫文件的使用步驟
a.編寫源程式xxx.c,如:vi main.c
b.只編譯不鏈接,生成目標文件.o
如: cc -c main.c
c.連接目標文件和靜態庫文件
1)直接連接
  cc main.o libadder.a
2)通過選項進行連接(掌握)
  cc main.o -l 庫名 -L 庫文件所在的路徑
  cc main.o -l adder -L .
3)配置環境變數LIBARARY_PATH
  export LIBRARY_PATH=$LIBRARY_PATH:.
  cc main.o -l adder

3.3 共用庫的生成和使用步驟
(1)共用庫的生成步驟
  a.編寫源程式xxx.c,如 vi adder.c
b.只編譯不鏈接生成.o目標文件
  gcc/cc -c -fpic/*小模式*/ adder.c
c.使用編譯選項生成共用庫文件
  gcc/cc -shared/*共用*/ adder.o -o lib庫名.so
(2)共用庫的使用步驟
a.編寫測試程式xxx.c,如 vi main.c
b.只編譯不鏈接生成.o目標文件
  如: cc -c main.c
c.連接測試文件和共用庫文件
1)直接連接
  cc main.o libadder.so
2)使用編譯選項進行連接(掌握)
  cc main.o -l adder -L .
3)配置環境變數LIBRARY_PATH
  export LIBRARY_PATH=$LIBRARY_PATH:.
  cc main.o -l adder
註意:
對於共用庫文件的使用來說,要求配置LD_LIBRARY_PATH
  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

 

共用庫的動態載入
(1)dlopen函數
#include <dlfcn.h>
void *dlopen(const char *filename, int flag);
第一個參數:字元串形式的文件名
第二個參數:載入標誌
RTLD_LAZY - 延遲載入
RTLD_NOW - 立即載入
返回值:返回共用庫文件的句柄/地址
函數功能:打開和載入共用庫文件,根據返回值來可以
操作該共用庫文件

(2)dlerror函數
char *dlerror(void);
函數功能:
主要用於獲取dlopen()/dlsym()/dlclose()/函數調用期間發生的最新錯誤信息,
通過返回值返回,返回NULL則沒有錯誤

(3)dlsym函數
void *dlsym(void *handle, const char *symbol);
第一個參數:dlopen函數的返回值
第二個參數:標識,一般用於查找具體的函數名
返回值:返回標識在記憶體中的地址
函數功能:
根據handle在對應的共用庫中查找名字為symbol標識的地址

(4)dlclose函數
int dlclose(void *handle);
函數功能:
表示關閉handle所對應的共用庫文件

註意:
連接的時候需要指定選項: -ldl

 

動態庫使用示例:

//加法計算的頭文件
#ifndef ADDER_H
#define ADDER_H

//計算兩個int類型參數的和
int add_int(int ia,int ib);
//計算兩個double類型參數的和
double add_double(double da,double db);

#endif
//加法計算的源文件
#include "adder.h"
//#include "../adder.h"

//計算兩個int類型參數的和
int add_int(int ia,int ib)
{
    return ia + ib;
}

//計算兩個double類型參數的和
double add_double(double da,double db)
{
    return da + db;
}

 

 

//共用庫的動態載入
#include <stdio.h>
#include <dlfcn.h>

int main(void)
{
    //1.打開和載入共用庫文件
    void* handler = dlopen("./shared/libadder.so",RTLD_NOW);
    //2.判斷是否出錯
    char* error = dlerror();
    if(error != NULL)
    {
        printf("載入共用庫文件失敗\n");
        return -1;
    }
    //3.尋找共用庫中指定的標識
    int (*add_pint)(int ia,int ib);
    add_pint = dlsym(handler,"add_int");
    //4.判斷是否出錯
    error = dlerror();
    if(error != NULL)
    {
        printf("獲取標識失敗\n");
        return -1;
    }
    //5.使用標識進行處理
    printf("計算的結果是:%d\n",add_pint(10,20));//30
    //6.關閉共用庫文件
    dlclose(handler);
    return 0;
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 聲明:本文所有的內容轉載於網路上,對原作者表示感謝 用於系統存儲管理的協處理器CP15 MCR{cond} coproc,opcode1,Rd,CRn,CRm,opcode2 MRC {cond} coproc,opcode1,Rd,CRn,CRm,opcode2 coproc 指令操作的協處理器名 ...
  • 1.SoC: SoC = System on Chip (在一個晶元裡面做一個系統) *System這裡可以理解為:整體的一個電路系統,完成一個具體功能的東西 *在早期,一個由Nand控制器、UART、LCD控制器、CPU構成的系統是在PCB板上,Nand控制器、UART、LCD控制器、CPU每一個 ...
  • 前言 MDK-ARM意思就是基於ARM的微控制器開發工具(Microcontroller Developer Kit),由Keil公司開發,MDK-ARM包含了工業標準的Keil C編譯器、巨集彙編器、調試器、實時內核等組件。具有業行領先的ARM C/C++編譯工具鏈,完美支持Cortex-M、Cor ...
  • 說一下剛學習uCOS的心得1)首先強調一下實時操作系統(RTOS)的特點,最明顯的是提供及時響應和高可靠性2)基於實施操作系統的應用程式設計中,其中很重要的一個概念是"任務",任務設計也就是任務函數的設計是整個整 個應用程式的基礎,其他軟體設計工作都是圍繞來展開的3)用戶任務函數中,必須包含至少一次 ...
  • ...
  • serdel是什麼 userdel 是一個底層用於刪除用戶的工具。在 Debian 上,我們通常會使用 deluser 命令。userdel 會查詢系統賬戶文件,例如 /etc/password 和 /etc/group。那麼它會刪除所有和用戶名相關的條目。在我們刪除它之前,用戶名必須存在。 如何使 ...
  • 預熱組件下載地址:下載地址 IIS預熱模塊配置界面插件:下載地址 Warm Up設定方式: (1) 應用程式池層級:只要有需要的應用程式池的Start Mode設定AlwaysRunning就可以 (2) 站點層級:選擇你們要做預熱的站點 通過以上兩步,就完成了warm up, 簡單吧。(IIS8 ...
  • - 什麼是性能調優?(what) - 為什麼需要性能調優?(why) - 什麼時候需要性能調優?(when) - 什麼地方需要性能調優?(where) - 什麼人來進行性能調優?(who) - 怎麼樣進行性能調優?(How) - 總結 # 什麼是性能調優?(what) # ![](http://i. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...