2010-02-14 8 views
10

Gibt es eine Möglichkeit, die Version einer Dylib mit ihrem Pfad zu finden? Ich suche nach etwas, das die gleichen Argumente wie dlopen akzeptiert. Ich habe NSVersionOfRunTimeLibrary angeschaut, aber nach dem Lesen der Dokumentation sieht es so aus, als würde es die Version des aktuellen Dylibs bekommen, nicht die im Pfad angegebene.Dylib-Version mit dlopen finden

Danke

Antwort

14

Run otool -L auf, und es wird seine tatsächlich Version zeigen. Ich wähle libSystem.B wie es andere Version in den 10.4 und 10.5 SDKs hat:

$ 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) 

(sehen, wie die erste hat 88.3.11 Version, während der zweite 111.1.4 hat). Dieses Beispiel zeigt auch, dass nicht alle Bibliotheken sind symbolische Links zu Dateien mit der Versionsnummer in ihnen:

$ 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 

Hier werden die Dateien nicht die Versionsnummer in ihrem Namen haben.

EDIT: eine zweite Lösung ist es, NSVersionOfRunTimeLibrary in einem Testprogramm zu verwenden, in dem Sie laden die Bibliothek, die Sie überprüfen möchten. Erstellen Sie ein Programm libversion aus der folgenden C-Quelle:

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

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

Dann rufen Sie es wie folgt aus:

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

(hier wird die Versionsnummer als hexadezimale gedruckt, aber Sie können an Ihre Bedürfnisse anpassen .)

+2

Viel bessere Antwort, meine gelöscht. – EightyEight

4

Sie können hier den Quellcode NSVersionOfRunTimeLibrary überprüfen: http://www.opensource.apple.com/source/dyld/dyld-132.13/src/dyldAPIsInLibSystem.cpp

auf tha Basierend t Sie können Ihre eigene Version erstellen, die if(names_match(install_name, libraryName) == TRUE) durch if(strcmp(_dyld_get_image_name(i), libraryName) == 0) ersetzt Das Problem beheben, dass das Original den Bibliotheksnamen ohne vollständigen Pfad erwartet, die bearbeitete Version erwartet den vollständigen Pfad, aber es wird immer noch in den geladenen Dylibs suchen.

#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

Sie antworten teilweise, aber dennoch sollte dies Teil der Lösung sein, denke ich. – Till

+0

In Bezug auf "Das wird das Problem beheben, dass es jetzt den vollständigen Namen erwartet": Ich glaube nicht, dass es wirklich ein Problem ist, wie Adk versucht, eine Bibliotheksversion durch seinen Pfad (der den Namen enthält) abzufragen. –

Verwandte Themen