dylib动态库加载顺序

dyld(the dynamic link editor):苹果动态链接编译器
研究在iOS中动态库的加载顺序是什么样子:
1.实验篇
(1)没有依赖关系:
在这里插入图片描述
制作dylibA、dylibB、dylibC三个动态库(不了解动态库制作的问度娘),且3个动态库间没有依赖关系,同时在每个库中添加一个Class,暂且以Class的load方法的调用顺序当做是动态库的加载顺序,比如dylibA:

@implementation ClassA
+ (void)load {
    NSLog(@"dylibA loaded");
}
@end

将三个库加到demo项目工程中,并且保证Build Phases-Link Binary With Libraries中的顺序:dylibA > dylibB > dylibC,运行结果:

Demo[53199:17384949] dylibA loaded
Demo[53199:17384949] dylibB loaded
Demo[53199:17384949] dylibC loaded

调整下Link Binary With Libraries中的顺序:dylibC > dylibB > dylibA,运行结果:

Demo[53265:17397552] dylibC loaded
Demo[53265:17397552] dylibB loaded
Demo[53265:17397552] dylibA loaded

通过实验知道:在没有依赖关系的情况下,动态库的加载顺序由Link Binary With Libraries中的拖入顺序决定,可以通过Link Binary With Libraries来控制动态库的加载顺序。
(2)单一依赖关系
在这里插入图片描述
dylibA依赖dylibB,dylibB依赖dylibC,简单改造三个库,如在dylibB中import下dylibC的头文件,dylibA中同理:


#import "ClassB.h"
#import <dylibC/dylibC.h>

@implementation ClassB
+ (void)load {
    NSLog(@"dylibB loaded");
}
@end

Link Binary With Libraries中顺序:dylibA > dylibB > dylibC运行结果:


Demo[53570:17450857] dylibC loaded
Demo[53570:17450857] dylibB loaded
Demo[53570:17450857] dylibA loaded

发现三个库的加载顺序是反的,修改顺序:dylibC > dylibA > dylibB,运行结果不变。结果可知:动态库的加载顺序还受依赖关系影响,被依赖的子节点优先加载。

(3)组合依赖关系
在这里插入图片描述
dylibA、dylibB、dylibC没有依赖关系,dylibA嵌入式依赖了dylibD、dylibE(dylibF)

Demo[97898:19286936] dylibD loaded
Demo[97898:19286936] dylibF loaded
Demo[97898:19286936] dylibE loaded
Demo[97898:19286936] dylibA loaded
Demo[97898:19286936] dylibB loaded
Demo[97898:19286936] dylibC loaded

通过修改dylibA-Link Binary With Libraries中dylibD、dylibE的顺序调整为:
在这里插入图片描述

Demo[97982:19305235] dylibF loaded
Demo[97982:19305235] dylibE loaded
Demo[97982:19305235] dylibD loaded
Demo[97982:19305235] dylibA loaded
Demo[97982:19305235] dylibB loaded
Demo[97982:19305235] dylibC loaded

总结动态库的加载顺序为:先根据拖入配置的链接顺序加载,如有依赖的先递归式加载依赖。

2.源码篇
通过几个实验对动态库的加载顺序有个大概的理解,下面我们通过源码进一步

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要获取某个动态库加载地址,可以使用 `dlopen` 函数以及其他一些辅助函数来实现。以下是获取动态库加载地址的一种方法: ```objective-c #include <dlfcn.h> void *getLibraryBaseAddress(const char *libraryName) { void *handle = dlopen(libraryName, RTLD_LAZY); if (handle != NULL) { Dl_info info; if (dladdr((const void *)getLibraryBaseAddress, &info) != 0) { dlclose(handle); return info.dli_fbase; } dlclose(handle); } return NULL; } ``` 在上述代码中,我们定义了一个名为 `getLibraryBaseAddress` 的函数,它接受一个参数 `libraryName` 表示要获取加载地址的动态库的名称。 在函数内部,我们使用 `dlopen` 函数来打开指定的动态库,并获取对应的句柄(handle)。如果成功打开动态库,则使用 `dladdr` 函数来获取当前函数(`getLibraryBaseAddress`)的符号信息。通过 `info.dli_fbase` 可以获取到动态库加载地址。最后,我们使用 `dlclose` 函数关闭动态库。 如果成功获取到动态库加载地址,则该地址将被返回。否则,返回 `NULL`。 使用示例: ```objective-c const char *libraryName = "libYourLibrary.dylib"; void *baseAddress = getLibraryBaseAddress(libraryName); if (baseAddress != NULL) { printf("The base address of %s is %p\n", libraryName, baseAddress); } else { printf("Failed to get the base address of %s\n", libraryName); } ``` 注意,这种方法在 iOS 应用程序中可能会受到沙盒限制,并且需要对目标动态库具有访问权限。另外,确保提供正确的动态库名称,并链接 `dlfcn.h` 头文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HaiJunYa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值