ios - 如何从其句柄(macOS/iOS)获取库的路径?

标签 ios xcode macos handle dylib

我有一个动态库的句柄(通过使用 dlopen())。不管为什么,我都无法访问提供给 dlopen() 的路径,但需要另一个函数的路径。因此,我需要能够使用其句柄获取库的路径。

我试过使用 dladdr(),就像我在应用程序的其他部分中所做的那样,但是在 macOS/iOS 上,您无法使用它来查找库的路径库句柄 它仅适用于库中符号的句柄。我可以尝试向库中添加一个“定位器符号”,并以这种方式完成任务,但我不想这样做。

我还尝试了 dlinfo()RTLD_DI_LINKMAP,但这在 macOS/iOS 上显然不可用。

最佳答案

令我惊讶的是,有关这方面的信息如此之少。许多解决方案在 macOS/iOS 上不可用。还有一些只是关于获取当前可执行文件的路径,与句柄无关。

经过大量搜索,我终于找到了一些资源,说要使用 _dyld_image_count()_dyld_get_image_name() 遍历所有加载的图像。我最初决定不这样做,因为它看起来不像是一种不合理的缓慢做事方式。

最终,我决定迭代所有加载的图像,因为这是我遇到的唯一实际解决方案。我在谷歌上搜索了示例,但找不到有关该主题的任何教程。但是,我确实遇到了实现该功能的开源 C++ 库(找到 here )。

我把它翻译成普通的 C,去掉了一些多余的东西(比如去掉句柄)。在测试过程中,我注意到我想要的库总是在列表的最后(我最好的猜测是它按照它们加载的顺序存储它们,并且由于我的不是系统库,它将是最后加载的)。这保证了缓慢的性能(引用计算机 - 对人类来说它仍然几乎是瞬时的)。因此,我做了一个巧妙的优化,从列表的结尾开始搜索,而不是开头。

这是我的解决方案的最终代码:

// NOT a thread safe way of doing things
NSString *pathFromHandle(void* handle)
{
    // Since we know the image we want will always be near the end of the list, start there and go backwards
    for (uint32_t i = (_dyld_image_count() - 1); i >= 0; i--)
    {
        const char* image_name = _dyld_get_image_name(i);

        // Why dlopen doesn't effect _dyld stuff: if an image is already loaded, it returns the existing handle.
        void* probe_handle = dlopen(image_name, RTLD_LAZY);
        dlclose(probe_handle);

        if (handle == probe_handle)
        {
            return [NSString stringWithUTF8String:image_name];
        }
    }


    return NULL;
}

请务必注意,此解决方案不是线程安全的,因为 _dyld_image_count()_dyld_get_image_name() 本质上不是线程安全的。这意味着任何其他线程都可以加载/卸载图像并对我们的搜索产生负面影响。

另外,resource我曾质疑为什么 dlopen_dyld_image_count() 没有影响。这是因为如果图像已经加载,dlopen 不会加载图像的新实例,而是返回它的现有句柄。

关于ios - 如何从其句柄(macOS/iOS)获取库的路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54201384/

相关文章:

xcode - 从框架确定 OS X SDK 和部署目标版本

ios - 使用 AVCaptureSession 录制视频

ios - 什么是适用于 iOS 的良好数据可视化库?

objective-c - xcode:如何在xcode中调试?

macos - 查找 TCP 版本

java - 无法在我的 mac Os X 上运行 Ant?

ios - 为什么我的 Swift 代码函数只运行一次?

iphone - 如何在 iPhone SDK 中列出所有文件夹及其子目录/文件?

ios - 如何将任何 GPX 文件转换为 Xcode 可接受的 GPX 文件

ios - 如何更改子类上的变量数据类型