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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...