1

我想得到 dylib 版本。我有一个 dylib 路径,我想为其获取版本号。我已经尝试过"otool -L"命令,它给了我正确的输出,但根据要求我不能使用它,因为我在一个目录中有 100 个 dylib,我想获取它的版本信息并且我不能运行“通过 NSTask 和 NSPipe 对每个 dylib 执行 otool" 命令。

我还找到了NSVersionOfLinkTimeLibrary()获取 dylib 版本的函数,但根据文档NSVersionOfLinkTimeLibrary返回链接库的版本号,而不是其他 dylib。

对此的任何帮助都会有所帮助。

谢谢。奥姆卡尔

4

2 回答 2

1

我已经通过编写自己的 dylib 解析器解决了这个问题。下面是代码片段

- (int64_t)getDylibVersion :(NSString *)dylibPth
{   
    const char* strFilePath = [dylibPth UTF8String];

    FILE* fileHandle = fopen(strFilePath, "rb");

    struct mach_header mh;
    if(fileHandle)
    {
        size_t bytesRead = fread(&mh, 1, sizeof(mh), fileHandle);

        if(bytesRead == sizeof(mh))
        {
            if((mh.magic == MH_MAGIC_64 || mh.magic == MH_MAGIC) && mh.filetype == MH_DYLIB)
            {               
                for(int j = 0; j < mh.ncmds; j++)
                {
                    union
                    {
                        struct load_command lc;
                        struct dylib_command dc;
                    } load_command;                 
                    if (sizeof(load_command.lc) != fread(&load_command.lc, 1, sizeof(load_command.lc), fileHandle))
                        goto fail;

                    switch (load_command.lc.cmd) 
                    {
                        case LC_SEGMENT:
                            break;
                        case LC_UUID:
                            break;
                        case LC_DYLD_INFO_ONLY:
                            break;
                        case LC_SYMTAB:
                            break;
                        case LC_LOAD_DYLIB:
                            break;
                        case LC_ID_DYLIB:
                        {
                            if (sizeof(load_command) - sizeof(load_command.lc) != fread(&load_command.lc + 1, 1, sizeof(load_command) - sizeof(load_command.lc), dylib_handle))
                                goto fail;
                            fclose(fileHandle);
                            return(load_command.dc.dylib.current_version);
                        }

                        default:
                            break;
                    }

                    if (0 != fseek(fileHandle, load_command.lc.cmdsize - sizeof(load_command.lc), SEEK_CUR))
                        goto fail;
                }
            }
        }
    }

fail:
    fclose(fileHandle);

    return (-1);
}

请注意,Mach-O dylib 版本号编码为 32 位无符号整数,主要版本在高 16 位,次要版本在 8 到 15 位,补丁级别在低 8 位:

uint32_t version = …;
uint32_t major = version >> 16;
uint32_t minor = (version >> 8) & 0xff;
uint32_t revision = version & 0xff;

另请注意,上述代码仅适用于“瘦”二进制文件。“胖”多架构二进制文件以胖头开始,您需要先协商它以找到适合您所需架构的切片。此外,以上仅适用于运行架构字节序的架构。

于 2013-02-10T09:13:18.680 回答
0

在我看来,你有两个选择。

  1. 将每个 dylib 加载到您的进程中并查找每个上的 Mach-O 标头,查找版本号。文档应该足够完整和彻底,以帮助您入门。

  2. 将每个 dylib 作为普通文件打开,并自己读取和解析 Mach-O 标头。这避免了必须将每个 dylib 加载到进程中,但这确实意味着您需要自己解析 Mach-O 二进制格式,或者找到一个可以为您完成它的库(我不知道任何顶部我的头)。

于 2013-02-08T22:59:55.040 回答