RTLD_LAZY通过动态库链接

问题描述 投票:6回答:3

我正在尝试找出RTLD_NOW和RTLD_LAZY标志之间的差异。我的查询是为什么RTLD_LAZY加载我从未引用过的函数的库。

我已经创建了dlrun.c文件

#include "stdio.h"
#include "dlfcn.h"
main()
{
void * ptr;
void (*fptr)(void);
printf("\nMy ID is- %d \n",getpid());
getchar();
ptr = dlopen("./fun5.so", RTLD_NOW);
if(ptr==NULL)
printf("failed to open fun5.so");
else
{
printf("I got fun5.so");
fptr= dlsym(ptr,"fun5");
getchar();
fptr();
printf("end of fun5");
dlclose(ptr);
}
}

下一个文件fun5.c为

#include "stdio.h"
void fun2(void);
void fun1(void);
fun5()
{
printf("I am in fun5");
getchar();
fun1();
} 
fun()
{
getchar(); 
fun2();
}

其他文件fun1.c是

#include "stdio.h"
fun1()
{
printf("I am in fun1");
getchar();
}  

并且文件fun2.c是

#include "stdio.h"
fun2()
{
printf("I am in fun2");
getchar();
}

然后我使用命令

gcc -c -fPIC -o fun1.o fun1.c
gcc -c -fPIC -o fun2.o fun2.c
gcc -c -fPIC -o fun5.o fun5.c
gcc -shared -o fun1.so fun1.o
gcc -shared -o fun2.so fun2.o
gcc -shared -o fun5.so fun5.o ./fun1.so ./fun2.so
gcc dlrun.c -o run -ldl
./run

现在我要检查哪些库由]加载>

cd /proc/<pid>
vi maps

这里看起来,在fun5.so之前未加载任何非标准的libray,在调用fun5函数之后,所有fun5.so,fun1.so和fun.2.so均按预期加载。现在,如果我将RTLD_NOW替换为RTLD_LAZY,则仅fun5.so和fun1.so应该被加载,因为我从未调用过fun()和fun2(),但fun2.so实际上也正在加载。所以我在哪里错?在创建fun5.so时我错了吗?如果是这样,那么我应该如何创建它?

谢谢

我正在尝试找出RTLD_NOW和RTLD_LAZY标志之间的差异。我的查询是为什么RTLD_LAZY加载从未引用过的函数的库。我创建了dlrun.c文件#include“ ...

linux dynamic-linking
3个回答
11
投票

下面的例子应该很清楚:


4
投票

RTLD_LAZY实际上意味着延迟解析符号,而不是延迟加载库。 fun5.so取决于这两个库,因此将在加载fun5.so时加载它们。


0
投票

跟随“ fliX”,您可以看到nm给出的示例:

© www.soinside.com 2019 - 2024. All rights reserved.