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

私の見方では、2 つの選択肢があります。

  1. 各 dylib をプロセスにロードし、それぞれの Mach-O ヘッダーを検索して、バージョン番号を探します。ドキュメントは、作業を開始するのに十分なほど完全で完全なものでなければなりません。

  2. 各 dylib を通常のファイルとして開き、Mach-O ヘッダーを自分で読み取って解析します。これにより、各 dylib をプロセスにロードする必要がなくなりますが、Mach-O バイナリ形式を自分で解析するか、それを実行できるライブラリを見つける必要があることを意味します (トップから何かを知りません)。私の頭の)。

于 2013-02-08T22:59:55.040 に答える