今天在学习运行时的动态链接时,我学习到了一下这个函数:
#include <dlfcn.h>
void *dlopen(const char *filename, int flag);
filename为共享库的路径,例如"./libvector.so",flag参数必须是RTLD_NOW或RTLD_LAZY,这两个参数的意义是是否立即对共享库中未定义符号进行解析,下面以RTLD_LAZY为例进行说明。
RTLD_LAZY是加载共享目标时可以传递给dlopen()的flag。
从语义上讲,程序是延迟解析符号还是现在解析符号没有区别,但是对于用dlopen()加载的对象,RTLD_LAZY的意思是“可能有无法解析的符号;在使用它们之前不要尝试解析它们。”这个标志目前只适用于函数符号,而不是数据符号。
这实际上意味着什么?为了解释这一点,考虑一个系统,它包含一个可执行文件X和共享库P(主对象)和S(次对象)。X使用dlopen()加载P,P加载S。假设P引用了函数some_function(),而该函数在S中定义。
如果X在没有RTLD_LAZY绑定的情况下打开P,那么符号 some_function() 不会得到解析——在加载时不会,以后也不会通过打开S来解析。但是,如果在加载P时提供的flag为RTLD_LAZY | RTLD_WORLD时,运行时链接器不会尝试解析符号some_function(),我们有机会在调用 some_function() 之前调用dlopen(“S”, RTLD_GLOBAL)。这样,P中的 some_function() 引用将由S中 some_function() 的定义来满足。