2013年11月12日 星期二

製作Library檔之實作

首先要先記住一個重要的觀念:
   
1. 靜態庫(Static library):
     特徵: 副檔名為 libxxx.a , 整個函數庫的所有數據都會被整合編譯進去目標程式中
     優點: 執行目標程式時不需要附帶外部的函數庫支持 , 因為所有使用的函數都已經被編譯進去了.
     缺點:  如果靜態函數庫改變了,那麼程式整個必須重新編譯, 另外利用靜態函數庫編譯整個檔案會很大

2. 動態庫(Shared object):
     特徵:附檔名為 libxxx.so , 編譯時並不會將動態庫編進目標程式中,而是程式執行到相對應的函數才會動態申請調用動態庫
     優點:因為動態庫並沒有編進目標程式中, 故目標程式檔案較小 ,動態庫的改變不影響本程式 , 所以動態庫的升級較方便.
     缺點: 我認為的缺點 , 就是執行程式時老是檢查Library path 的路徑有沒有缺少那一個library等等, 系統預設放在/usr/lib.



然後複習一下編譯流程:





  • 靜態庫的使用:
             使用工具:       gcc  、 ar(用來建立靜態庫文件等等)
                (1). 建立hello1.c 、 hello2.c 分別如下:
                         
                       hello1.c      --->    void hello1() { printf("hello1\n");}
                       hello2.c      --->    void hello2() { printf("hello2\n");}
                       
              (2). generate object file:
                    # gcc -c hello1.c hello2.c

              (3). generate the library from object file:
                    # ar -crs libhello.a  hello1.o hello2.o    靜態庫已建立完成(libhello.a包了兩個function).
 
             (4). 連結靜態庫:
                    main.c  ---->   void main() { hello1(); hello2(); }
                       編譯  --->     # gcc -o  main  -L. -lhello  
           
                       執行  --->     #./main        //將會列印出兩個hello1 、 hello2

  • 動態庫的使用:
  程式引用上面的hello1.c 、 hello2.c
              (1). 產生動態庫:

                      gcc -fpic -shared -o libhello_func.so hello1.c hello2.c

              (2.)  連結動態庫:

                     gcc -o main  main.c    libhello_func.so     (注意, 加上libhello_func.so只是告知編譯認得main裡面的function).
      
                或  gcc -o main main.c -L. -lhello_func   
                    (-L. 指引當前目錄至library_path , -lhello_func會根據命名規則找到libhello_func).

              
              (3). 直接在程式中打開連結動態庫:
                    藉由使用到C語言標準庫 dlopen 、 dlsym 、 dlerror 、 dlclose 等等的開啟動態庫函數.
                    此方法可以不用在編譯器指引library ,  直接在程式中連結動態庫.

                     不過編譯時要注意 要加" -ldl " 引數來調用dlopen等等相關函數, 例如:
                      gcc -o main main.c –ldl 


              注意一點   , Linux預設的Library path 都在 /usr/lib 或是 /lib , 因此你可以選擇將library.so 放置這裡 ,

              亦或是宣告指定的library path 讓系統找到, 
              --> export LD_LIBRARY_PATH = {libhello_func.so的目錄}:$LD_LIBRARY_PATH


            Reference :

沒有留言:

張貼留言