Linux GCC編譯使用動態、靜態連接庫

在windows下動態連接庫是以.dll後綴的文件,二在Linux中,是以.so做後綴的文件。linux

動態連接庫的好處就是節省內存空間。


一、Linux下建立動態連接庫
在使用GCC編譯程序時,只需加上-shared選項便可,這樣生成的執行程序即爲動態連接庫。
例若有文件:hello.c x.h main.cwindows

[plain] view plain copy.net

  1. 編譯:gcc hello.c -fPIC -o libhello.so  



其中-fPIC選項的做用是:表示編譯爲位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的,
因此動態載入時是經過代碼拷貝的方式來知足不一樣的調用,而不能達到真正的代碼段共享的目的.


將main.c與hello.so動態庫命令行

[plain] view plain copyblog

  1. gcc main.c -L. -lhello -o main  

 

1、動態連接庫內存

1.建立hello.so動態庫文檔

[cpp] view plain copyget

  1. #include <stdio.h>  
  2. void hello(){  
  3.     printf("hello world\n");  
  4. }  
  5. 編譯:gcc -fPIC -shared hello.c -o libhello.so  


2.hello.h頭文件編譯器

[cpp] view plain copyit

  1. void hello();  


3.連接動態庫

[cpp] view plain copy

  1. #include <stdio.h>  
  2. #include "hello.h"  
  3.   
  4. int main(){  
  5.     printf("call hello()");  
  6.     hello();  
  7. }  
  8. 編譯:gcc main.c -L. -lhello -o main  

這裏-L的選項是指定編譯器在搜索動態庫時搜索的路徑,告訴編譯器hello庫的位置。"."意思是當前路徑.

 

3.編譯成夠後執行./main,會提示:

[plain] view plain copy

  1. In function `main':  
  2.    
  3. main.c:(.text+0x1d): undefined reference to `hello'  
  4. collect2: ld returned 1 exit status  

這是由於在連接hello動態庫時,編譯器沒有找到。
解決方法:

[plain] view plain copy

  1. sudo cp libhello.so /usr/lib/  

這樣,再次執行就成功輸入:
call hello()

 

2、靜態庫

文件有:main.c、hello.c、hello.h
1.編譯靜態庫hello.o: 

[plain] view plain copy

  1. gcc hello.c -o hello.o  #這裏沒有使用-shared  


2.把目標文檔歸檔

[plain] view plain copy

  1. ar -r libhello.a hello.o  #這裏的ar至關於tar的做用,將多個目標打包。  

程序ar配合參數-r建立一個新庫libhello.a,並將命令行中列出的文件打包入其中。這種方法,若是libhello.a已經存在,將會覆蓋如今文件,不然將新建立。

3.連接靜態庫

[plain] view plain copy

  1. gcc main.c -lhello -L. -static -o main  

這裏的-static選項是告訴編譯器,hello是靜態庫。
或者:

[plain] view plain copy

  1. gcc main.c libhello.a -L. -o main  

這樣就能夠不用加-static

4.執行./main

輸出:call hello()

 

3、藉助自帶的ldd實現程序來分析動態庫搜索狀況

ldd main

結果: linux-gate.so.1 =>  (0x00efd000) libhello.so => /usr/lib/libhello.so (0x00f6b000) libc.so.6 => /lib/libc.so.6 (0x001a5000) /lib/ld-linux.so.2 (0x00eb8000) 若是目標程序沒有連接動態庫,則打印「not a dynamic executable」

相關文章
相關標籤/搜索