我已经通过编写自己的 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;
另请注意,上述代码仅适用于“瘦”二进制文件。“胖”多架构二进制文件以胖头开始,您需要先协商它以找到适合您所需架构的切片。此外,以上仅适用于运行架构字节序的架构。