日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

装入归档文件时出现了一个错误linux_静态链接与动态链接(Linux)

發布時間:2024/7/19 linux 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 装入归档文件时出现了一个错误linux_静态链接与动态链接(Linux) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

上一篇分享了靜態鏈接與動態鏈接的實驗(Windows下)。這一篇分享Linux下的筆記,同時對上一篇筆記做一個補充。

首先,我們把靜態鏈接與動態鏈接做一個這樣子的比喻:

把鏈接過程看做我們平時學習時做筆記的過程。我們平時學習時準備一本筆記本專門記錄我們的學習筆記,比如在某本書的某一頁上看到一個很好很有用的知識,這時候我們有兩種方法記錄在我們的筆記本上,一種是直接把那一頁的內容全部抄寫一遍到筆記本上(靜態鏈接);另一種是我們在筆記本上做個簡單的記錄(動態鏈接),比如寫上:xxx知識點在《xxx》的xxx頁。

從這兩種方法中我們可以很清楚地知道兩種方式的特點,第一種方式的優點就是我們在復習的時候就很方便,不用翻閱其它書籍了,但是缺點也很明顯,就是占用筆記本的空間很多,這種方法很快就把我們的筆記本給寫滿了。第二種方式的優點就是很省空間,缺點就是每當我們復習的時候,手頭上必須備著相關的參考書籍,比如我們去教室復習的時候,就得背著一大摞書去復習,這樣我們復習的效率可能就沒有那么高了。

這對應到我們的動態鏈接與靜態鏈接上是不是就很好理解了:

靜態鏈接與動態鏈接的主要優缺點

(1)靜態鏈接的優缺點:

優點:

  • 代碼裝載速度快,執行速度略比動態鏈接庫快;

缺點:

  • 使用靜態鏈接生成的可執行文件體積較大,包含相同的公共代碼,造成浪費。

(2)動態鏈接的優缺點:

優點:

  • 生成的可執行文件較靜態鏈接生成的可執行文件小;

缺點:

  • 速度比靜態鏈接慢;

動態、靜態鏈接實驗

我們先編寫如下代碼(共三個文件):

文件1(main.c):

#include "test.h"?void print_hello(void){ printf("hello world");}

文件2(test.c):

#ifndef __TEST_H#define __TEST_H?#include ?void print_hello(void);?#endif

文件3(test.h):

#ifndef __TEST_H#define __TEST_H#include void print_hello(void);#endif

1、動態鏈接實驗

首先,將源文件生成目標文件(*.o),命令:

gcc -c -fPIC main.c test.c

這里得根據實際編譯環境加上或者不加上-fPIC參數,這個是與gcc的版本有關,像我這邊的gcc 5.4.0就得顯示加上-fPIC這個參數,若是不加,則會影響下一步的鏈接過程。

在Linux中,動態庫的擴展名一般為.so。針對上面生成的test.o文件,生成動態庫的命令為:

gcc -shared test.o -o libtest_d.so

若是上一步不加-fPIC參數,則會產生如下錯誤:

大概意思就是.rodata不可以拿來制作共享文件,請加上-fPIC參數重新編譯。問題分析:

-fPIC 作用于編譯階段,告訴編譯器產生與位置無關代碼(Position-Independent Code),則產生的代碼中,沒有絕對地址,全部使用相對地址,故而代碼可以被加載器加載到內存的任意位置,都可以正確的執行。這正是共享庫所要求的,共享庫被加載時,在內存的位置不是固定的。

從gcc來看,shared應該是包含fPIC選項的,但似乎不是所有的版本都支持,所以最好顯式加上fPIC選項。

使用鏈接動態庫的方式生成可執行程序,命令:

gcc main.o -L. -ltest_d -o test_d.out

這里的-L.的含義是在搜索庫文件時包含當前目錄,-ltest_d的含義是鏈接名稱為libtest_d.so的動態鏈接庫。

下面運行test_d.out程序,發現出現如下錯誤:

不能找到共享庫文件libtest_d.so,加載失敗。因為一般情況下Linux會在/usr/lib路徑中搜索需要用到的庫,而libtest_d.so庫并不在這個路徑下。解決方法有兩種:一種就是把這個文件拷貝至/usr/lib路徑下,但是一般不允許這樣做,一般用戶也不允許往這個路徑里拷貝東西。另一種就是把當前路徑增加為動態庫的搜索路徑,命令為:

export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH

這時候就可以正常運行了:

2、靜態鏈接實驗

靜態庫用ar工具來制作。ar是一個歸檔工具,用于建立、修改、提取歸檔文件(archive)。一個歸檔文件可以包含多個目標文件,也被稱為靜態庫。在Linux下,靜態庫的擴展名一般為.a。

把目標文件test.o做成靜態庫,命令:

ar -rv libtest_s.a test.o

其中rv參數為組合參數,其中r參數表示當建立的模塊名已經存在時,則覆蓋同名模塊,v參數用來顯示附加信息,比如被處理的文件的名字。

使用鏈接靜態庫的方法生成可執行程序,命令:

gcc main.o -L. -ltest_s -o test_s.out

運行程序:

刪除靜態庫之后,可執行程序也是能正常運行的。事實上,使用鏈接靜態庫的方式生成的可執行程序與直接使用目標文件生成的可執行程序沒有區別。只是經過了靜態庫的鏈接,變為了一個文件,方便于調用、移植和保存。

歸檔工具ar可以很方便地查看和刪除歸檔文件中的成員。

查看靜態庫libtest_s.a中的內容,命令:

關于ar工具更多的命令參數可輸入ar --help進行查看:

以上就是關于靜態鏈接與動態鏈接的Linux筆記,如有錯誤,歡迎指出!

總結

以上是生活随笔為你收集整理的装入归档文件时出现了一个错误linux_静态链接与动态链接(Linux)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。