2010-12-10 57 views
6

如果我構建共享庫(共享對象),我可以通過以下兩種方式使用它:第一種方法是使用共享庫,就像我將使用靜態庫一樣。Unix上共享庫的困境

  #include "myLib.h" 
      //... 
      //afterwards I can use functions defined in mylib.h 
      myFunction(); 

使用共享庫的第二種方法是通過調用動態加載器API函數:dlopendlsym,和從dlfcn.hdlclose。例如,當我想實現插件模式時,我會以這種方式使用共享庫。清單應該是這樣的:

#include <dlfcn.h> 

void *myLib;    /* Handle to shared lib file */ 
void (*myFunction)();  /* Pointer to loaded function */ 

    //... 

    //load shared object 
    myLib = dlopen("/home/dlTest/myLib.so",RTLD_LAZY); 
    dlerror(); 

    //get handle to function 
    myFunction = dlsym(myLib, "myFunction"); 
    dlerror(); 

    //execute function 
    (*myFunction)(); 

    //close lib 
    dlclose(myLib); 
    dlerror(); 

現在我的第一個問題是:是什麼在加載時間上的共享對象的這兩種用法之間的區別?通過第一種方式使用共享庫,我們在加載時將共享庫鏈接/加載到主應用程序,第二種方式是在運行時間做同樣的事情?

第二個問題。這兩種用法的名稱是什麼? 第一個被稱爲靜態鏈接共享庫,第二個是動態鏈接/加載共享庫?

第三個問題如果我已經建立了一個共享庫沒有-fPIC標誌(osition無關的代碼),我將能夠以第二種方式來使用它?

Cheers

回答

4

這兩種使用模式通常被稱爲隱式和顯式。正如您正確地說明的那樣,加載的區別在於,在執行dlopen時加載顯式鏈接的動態庫,並在應用程序加載到內存中時加載隱式鏈接庫。每個dlopen的可以在幾毫秒來完成,除非庫已經加載,在這種情況下,它的速度非常快,所以如果你有非常嚴格的時延需求或需要做頻繁的裝載/然後卸載你可以決定讓聯隱含或明確加載庫在程序啓動時,不要卸載它,直到它不再使用。

+0

如果我更改共享庫並重新編譯它,我必須重新鏈接使用該共享庫,如果我使用隱式連接所有主要的應用程序,或者它完成時自動這些應用程序的負載? – 2010-12-11 17:24:18

5

的主要區別是在錯誤處理。隱式更容易,但如果出現問題(庫缺失或函數不在庫中),程序將無法運行。使用顯式加載時,您可以檢查dlopen/dlsym調用錯誤,如果出現問題,請回退一些替代方法。

要回答你的第三個問題,它實際上取決於系統的架構,但在大多數的ABI仍可以加載不-PIC編譯共享對象,但它可能是加載較慢,需要更多的內存。

+0

如果我更改共享庫並重新編譯它,我必須重新鏈接使用該共享庫,如果我使用隱式連接所有主要的應用程序,或者它完成時自動這些應用程序的負載? – 2010-12-11 17:24:36

+0

@kobac:no - 共享庫在加載時總是鏈接的,無論是在應用程序啓動時,還是在調用dlopen時 – 2010-12-12 05:13:19