2013-02-08 149 views
1

我想获得dylib版本。我有一个dylib路径,我想获取版本号。 我试过"otool -L"命令,它给了我适当的输出,但根据要求我不能使用它,因为我有一个目录中的dylib 100我想获取版本信息,我不能通过NSTask和NSPipe为每个dylib运行“otool”命令。如何获取目录中的dylib版本信息

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

对此的任何帮助将有所帮助。

谢谢。 Omkar

回答

0

我看到它的方式,你有2个选项。

  1. 将每个dylib加载到您的进程中,然后查找每个dylib,查找版本号。 documentation应该是完整和彻底的,足以让你开始。

  2. 打开每个dylib作为普通文件,并自己读取并解析Mach-O标题。这样可以避免必须将每个dylib加载到进程中,但是这意味着您需要自己分析Mach-O二进制格式,或者找到一个可以为您执行的库(我不知道顶部有什么)我的头)。

+0

谢谢布拉德利。 – Omkar 2013-02-10 09:09:23

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版本号通常是在高16位编码为32位无符号整数,主要版本,通过15次版本中位8,以及补丁级别中的低8位:

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

还要注意的是,上述代码将只为“薄”的二进制文件工作。 “胖”的多体系结构二进制文件首先使用胖头,您需要首先进行协商以找到所需体系结构的片。此外,以上只适用于运行架构的字节顺序架构。