dra*_*vic 6 c++ unix linux shared-libraries
如果我构建一个共享库(共享对象),我可以通过以下两种方式使用它:
第一种方法是使用共享库,就像我使用静态库一样.
#include "myLib.h"
//...
//afterwards I can use functions defined in mylib.h
myFunction();
Run Code Online (Sandbox Code Playgroud)
使用共享库的第二种方法是通过调用动态加载器API函数:dlopen,dlsym,和dlclose从dlfcn.h.例如,当我想实现插件模式时,我会以这种方式使用共享库.清单看起来像这样:
#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();
Run Code Online (Sandbox Code Playgroud)
现在我的第一个问题是:在加载时间方面,共享对象的这两种用法有什么区别?通过第一种方式使用共享库,我们在加载时将链接/加载到主应用程序,在第二种方式我们在运行时做同样的事情?
第二个问题.这两种用法的名称是什么?第一个是静态链接共享库,第二个是动态链接/加载共享库?
第三个问题如果我构建了一个没有-fPIC标志(独立于代码的代码)的共享库,我能以第二种方式使用它吗?
干杯
这两种使用模式通常称为隐式和显式.正确地说明了加载的不同之处在于,当执行dlopen时加载了显式链接的动态库,并且在应用程序加载到内存时加载了隐式链接库.每个dlopen可能需要几毫秒才能完成,除非已经加载了库,在这种情况下它非常快,所以如果你有非常严格的延迟要求或需要经常加载/卸载那么你可能决定隐式或显式加载库在程序启动时,不要卸载它,直到它不再使用.
主要区别在于错误处理.隐式更容易,但如果出现问题(库缺失或函数不在库中),程序将无法运行.使用显式加载,您可以检查dlopen/dlsym调用是否存在错误,如果出现问题,请回退一些替代方案.
要回答第三个问题,它实际上取决于体系结构,但在大多数ABI上,您仍然可以加载没有-PIC编译的共享对象,但加载速度可能较慢并且需要更多内存.