2010-02-14 12 views
10

경로를 사용하여 dylib의 버전을 찾는 방법이 있습니까? 나는 dlopen과 같은 주장을 받아들이는 어떤 것을 찾고있다. 나는 NSVersionOfRunTimeLibrary를 보았습니다. 그러나 문서를 읽었을 때 경로에 지정된 것이 아니라 현재 dylib의 버전을 얻는 것처럼 보입니다. dlopen을 사용하여 dylib 버전 찾기

당신에게 그것에

답변

14

실행 otool -L 감사, 그리고 그것의 실제 버전을 표시합니다. 나는 그것이 10.4 및 10.5 SDK를 다른 버전이로 libSystem.B를 선택

$ otool -L /Developer/SDKs/MacOSX10.4u.sdk/usr/lib/libSystem.B.dylib 
/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/libSystem.B.dylib: 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.3.11) 
    /usr/lib/system/libmathCommon.A.dylib (compatibility version 1.0.0, current version 220.0.0) 
$ otool -L /Developer/SDKs/MacOSX10.5.sdk/usr/lib/libSystem.B.dylib 
/Developer/SDKs/MacOSX10.5.sdk/usr/lib/libSystem.B.dylib: 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.4) 
    /usr/lib/system/libmathCommon.A.dylib (compatibility version 1.0.0, current version 292.4.0) 

(첫 번째는 88.3.11 버전이 어떻게 두 번째는 111.1.4있는 동안, 참조). 이 예제는 또한 모든 라이브러리가 그 안에 버전 번호가있는 파일에 대한 심볼릭 링크임을 보여줍니다.

$ ll /Developer/SDKs/MacOSX10.*.sdk/usr/lib/libSystem.B.dylib 
-rwxr-xr-x 1 root wheel 749K May 15 2009 /Developer/SDKs/MacOSX10.4u.sdk/usr/lib/libSystem.B.dylib 
-rwxr-xr-x 1 root wheel 670K May 15 2009 /Developer/SDKs/MacOSX10.5.sdk/usr/lib/libSystem.B.dylib 
-rwxr-xr-x 1 root wheel 901K Sep 25 00:21 /Developer/SDKs/MacOSX10.6.sdk/usr/lib/libSystem.B.dylib 

여기서 파일의 이름에는 버전 번호가 없습니다.

편집 : 두 번째 해결 방법은 검사 할 라이브러리를 강제로로드하는 테스트 프로그램에서 NSVersionOfRunTimeLibrary을 사용하는 것입니다. 다음 C 소스에서 프로그램 libversion 만들기 :

#include <stdio.h> 
#include <mach-o/dyld.h> 

int main (int argc, char **argv) 
{ 
    printf ("%x\n", NSVersionOfRunTimeLibrary (argv[1])); 
    return 0; 
} 

그런 다음, 당신이 그런 식으로 전화 :

$ DYLD_INSERT_LIBRARIES=/usr/lib/libpam.2.dylib ./a.out libpam.2.dylib 
30000 

을 (여기에서, 버전 번호를 16 진수로 인쇄됩니다,하지만 당신은 당신의 요구에 적응할 수 .)

+2

더 나은 대답, 삭제 된 내. – EightyEight

4

당신은 여기 NSVersionOfRunTimeLibrary의 소스 코드를 확인할 수 있습니다 http://www.opensource.apple.com/source/dyld/dyld-132.13/src/dyldAPIsInLibSystem.cpp

그쪽을 바탕으로 if(names_match(install_name, libraryName) == TRUE)if(strcmp(_dyld_get_image_name(i), libraryName) == 0) 으로 대체하는 자체 버전을 만들 수 있습니다. 원본 경로가 전체 경로없이 예상되는 문제를 해결할 수 있습니다. 편집 된 버전은 전체 경로를 예상하지만로드 된 dylib를 계속 검색합니다.

#include <mach-o/dyld.h> 
int32_t 
library_version(const char* libraryName) 
{ 
    unsigned long i, j, n; 
    struct load_command *load_commands, *lc; 
    struct dylib_command *dl; 
    const struct mach_header *mh; 

    n = _dyld_image_count(); 
    for(i = 0; i < n; i++){ 
     mh = _dyld_get_image_header(i); 
     if(mh->filetype != MH_DYLIB) 
     continue; 
     load_commands = (struct load_command *) 
#if __LP64__ 
       ((char *)mh + sizeof(struct mach_header_64)); 
#else 
       ((char *)mh + sizeof(struct mach_header)); 
#endif 
     lc = load_commands; 
     for(j = 0; j < mh->ncmds; j++){ 
     if(lc->cmd == LC_ID_DYLIB){ 
      dl = (struct dylib_command *)lc; 
      if(strcmp(_dyld_get_image_name(i), libraryName) == 0) 
      return(dl->dylib.current_version); 
     } 
     lc = (struct load_command *)((char *)lc + lc->cmdsize); 
     } 
    } 
    return(-1); 
} 
+0

부분적으로 대답하고는 있지만 여전히 솔루션의 일부가되어야한다고 생각합니다. – Till

+0

"이제는 전체 이름이 필요하다는 문제가 해결 될 것입니다.": adk이 경로 (이름을 포함)로 라이브러리 버전을 쿼리하려고 할 때 실제로 문제가 아닌 것 같습니다. –