Linux中編譯動態庫

來源:互聯網
上載者:User

類似Windows系統中的動態連結程式庫,Linux中也有相應的共用庫用以支援代碼的複用。Windows中為*.dll,而Linux中為*.so,我來詳細的告訴你如何在linux下編寫動態庫,以及如何使用它.

linux下編寫動態連結程式庫的步驟:

 

1.      編寫庫的標頭檔和源檔案.

2.      把所有涉及到的源檔案用如下方式編譯為目標檔案:

 

g++/gcc -g -c -fPIC -o library1.o library1.cpp

g++/gcc -g -c -fPIC -o library2.o library2.cpp
      ......

......

(注釋:-fPIC指通過這個選項來產生與位置無關的代碼,可以在任何地址被串連和裝載,-c指只編譯而不串連原程式)

 

3.      把所有的目標檔案連結為動態庫:

 

g++/gcc -g -shared -Wl,-soname,lib***.so -o lib***.so.1.0.0 library1.o library2.o ....  -lc

                

    (注釋:-lc選項,表示使用c語言庫,一般都要用到)

 

4.      建立一個庫名連結

 

ln -s lib***.so.1.0.0 lib***.so

 

現在你就可以引用庫了.下面我分別給出簡單例子告訴你如何動態和靜態使用動態庫:

假如你的應用程式原始碼叫testlib.cpp

採用/如下方式編譯:

 

      g++ -g -o testlib testlib.cpp -ldl

            

    (注釋:-ldl選項,表示產生的對象模組需要使用共用庫)

 

////////這個例子告訴你如何動態調用.so庫

testlib.cpp

#include <dlfcn.h>

#include <iostream.h>

#include ...

int main()

{

       void *handle=NULL;

       //define a pointer which will point to the function in the lib you want to use.

       YourFuntionType (*pFunc)(YourFunctionPerameterList........);

       //open the lib you want to use.

       handle=dlopen("/../../../yourlib.so",RTLD_LAZY);

       if(handle==NULL)

       {

              cout<<"failed loading library!"<<endl;

              return -1;

       }

       dlerror();

       //try to load the function in lib

       pFunc=(YourFuntionType(*)(YourFunctionPerameterList))dlsym(handle,"YourFuntionName");

       if(dlerror()!=NULL)

       {

              cout<<"Loading function in lib error!"<<endl;

              return -1;

       }

       //now you can use the funtion like this

       (*pFunc)(YourFuntionPerameterList);

       return 0;

}  

 

(注釋:dlopen()

              第一個參數:指定共用庫的名稱,將會在下面位置尋找指定的共用庫。

-環境變數LD_LIBRARY_PATH列出的用分號間隔的所有目錄。

-檔案/etc/ld.so.cache中找到的庫的列表,用ldconfig維護。

-目錄usr/lib。

-目錄/lib。

-目前的目錄。(這裡就是這種情況)

 

第二個參數:指定如何開啟共用庫。

-RTLD_NOW:將共用庫中的所有函數載入到記憶體

-RTLD_LAZY:             會推後共用庫中的函數的載入操作,直到調用dlsym()時方載入某函數

dlsym()

          調用dlsym時,利用dlopen()返回的共用庫的phandle以及函數名稱作為參數,返回要載入函數的入口地址。

       dlerror()

    該函數用於檢查調用共用庫的相關函數出現的錯誤。

 

特別需要注意的幾點問題:

1.      當你想用c++寫動態庫的時候,記住千萬別忘了在標頭檔裡面加上如下內容,否則產生的庫在動態調用的時候會出問題!!!!!!!

 #ifdef __cplusplus
       extern "C" {

#endif

....

....

   #ifdef __cplusplus

}

#endif 

 

2.      當你的庫中包括與omniORB3相關的東西的時候,一定要在makefile中加上 -D__x86__ -D__OSVERSION=4

 

/////////////這個例子告訴你如何靜態調用.so庫

首先你得確保你的應用程式能夠找到你的.so庫,這可以有幾種方法來實現.

方法一:

1.你可以把YourLib.so.1.0.0 和YourLib.so放到/usr/lib中,然後執行命令:ldconfig,這樣你就可以在你的應用程式中直接調用你庫中的函數了,當然你 得把庫的標頭檔包含到你的應用程式中

2.編譯你的應用程式

g++/gcc -g -o yourapp yourapp.cpp –lYourLib

 

方法二:

1.你也可以採用在系統中設定環境變數的辦法來實現. 在root目錄下:

vi .bash_profile

然後添加LD_LIBRARY=/../YourDirIncludingYourLib

然後注消一次,環境變數就生效了,這樣你就可以在你的應用程式中直接調用庫中的函數了,同樣你得有標頭檔.

2.編譯你的應用程式

g++/gcc -g -o yourapp yourapp.cpp –lYourLib

 

方法三:

你可以直接採用在編譯連結的時候告訴系統你的庫在什麼地方
       g++/gcc -g -o yourapp yourapp.cpp -L/YourDirIncludingYourLib –lYourLib

/////////////////////////////////

假如你的庫中有個函數:int eat(.....)

那麼採用如下方式調用它

yourapp.cpp

#include "YourLib.h"

int main()

{

       eat();

return 0;

}

 

是不是很easy?對了在靜態調用的時候好像不存在上面的"注意1"的問題,不過鑒於保險起見,最好還是按照標準的方式寫c++標頭檔吧,這絕對是個好習慣.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.