2010-12-10 60 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