2016-06-27 31 views
15

Supponiamo di avere diversi file di intestazione e libreria nella stessa directory. Se non so a quale libreria dovrei collegarmi, posso determinare a livello di codice quale libreria deve essere utilizzata.È possibile identificare la libreria che corrisponde a determinati file di intestazione?

Diciamo che ho provato a compilare il mio codice, e il linker si è lamentato di simboli esterni non risolti, c'è qualcosa che posso fare, sapendo che la libreria corretta esiste nella stessa directory?

+1

Stai avendo "versione" diversa (come uno filettato, una statica, etc.) della stessa libreria, o è più librerie davvero diversi tutti messi in una singola directory? –

+0

più librerie diverse –

+0

per Linux (almeno Debian e Kubuntu con i fratelli), installare apt-file e cercare 'ricerca di apt-file'. Spero che le distribuzioni basate su rpm come suse e redhat abbiano qualcosa di simile. –

risposta

5

Penso che la risposta a questa domanda possa essere di grande aiuto: Tools for inspecting .lib files?.

È possibile scrivere uno script semplice che esegue il ciclo di tutti i file lib nella directory e chiama dumpbin per scaricare i simboli di tutte le librerie in un file avviato con il nome lib, quindi in seguito è possibile cercare il simbolo di cui si ha bisogno in il file generato per ottenere la lib corretta.

+0

o 'nm' su tutto tranne Windows. – o11c

2

"È possibile determinare a livello di codice quale libreria deve essere utilizzata."

Non all'interno dello stesso programma/codebase. L'abilità "programmatica" (ad esempio template ecc.) Rimane fino alla fase di compilazione. Una volta che il collegamento inizia (a partire da oggi), il controllo è sparito.

"C'è qualcosa che posso fare, sapendo che la libreria corretta esiste nella stessa directory?"

Nuovamente n.. Non ho intenzione di demotivarti, ma quello che stai chiedendo non sarà comunque utile. Supponiamo, in qualche modo riesci a trovare un modo per sapere se la libreria esiste nella stessa directory. Quale scopo servirà? Perché praticamente una biblioteca può risiedere in qualsiasi percorso. Uno deve semplicemente impostare le variabili di percorso nell'MSVC o nell'opzione -L in gcc. Quindi la questione di avere la libreria nella stessa directory è discutibile.

Probabilmente potresti voler chiedere, come sapere se la libreria esiste nel tuo sistema & dove.
Bene, questo non è possibile in modo programmatico nella stessa base di codice. Perché devi eseguire quel codebase per trovare se la libreria esiste da qualche parte nel tuo sistema. Per eseguire quel codebase, devi collegarlo. Problema dell'uovo di gallina
O si controlla manualmente o si scrive il proprio script/codice separato per svolgere questa attività.

0

Forse è meglio usare la dll GetProcAddress function in C++ o se si scrive per sé lib è possibile aggiungere codice nell'intestazione come questo: '#' pragma comment (lib, "libname.lib") speranza il suo aiuto

0

Recentemente ho imparato più C++ e ho avuto una domanda simile. La maggior parte delle librerie e delle intestazioni sembrano almeno condividere un nome simile, ma le differenze tra "libm" e "math.h" mi hanno davvero chiesto come determinarlo in modo più sistematico.

Per entrambe le librerie statiche e dinamiche, uno strumento che ho trovato utile è readelf e il comando che mi piace è questo:

readelf --symbols <elf_file> | sed -ne '/FUNC/p' 

Così, per il mio esempio motivante:

$ readelf --symbols /lib/libm.so.5 | sed -ne '/FUNC/p' 
    2: 0000000000000000 476 FUNC WEAK DEFAULT UND [email protected]_1.0 (8) 
    4: 0000000000000000 62 FUNC GLOBAL DEFAULT UND [email protected]_1.0 (8) 
    5: 0000000000000000 310 FUNC GLOBAL DEFAULT UND [email protected]_1.0 (8) 
    6: 0000000000000000 41 FUNC GLOBAL DEFAULT UND [email protected]_1.0 (8) 
    9: 0000000000000000  8 FUNC GLOBAL DEFAULT UND [email protected]_1.0 (8) 
    11: 0000000000000000 16 FUNC GLOBAL DEFAULT UND [email protected]_1.0 (8) 
    12: 0000000000000000 53 FUNC GLOBAL DEFAULT UND [email protected]_1.0 (8) 
    14: 0000000000000000 84 FUNC GLOBAL DEFAULT UND [email protected]_1.0 (8) 
    16: 0000000000004ed0  6 FUNC GLOBAL DEFAULT 12 [email protected]@FBSD_1.0 
    17: 0000000000019930 405 FUNC GLOBAL DEFAULT 12 [email protected]@FBSD_1.3 
    18: 0000000000016590 600 FUNC GLOBAL DEFAULT 12 [email protected]@FBSD_1.0 
    ... 

Questo comando funziona anche per i file di archivio ar come libcurl.a.

Così qui si possono vedere le funzioni definite nella libreria. Da lì ho confrontato visivamente i nomi nella colonna finale come "log10l" con quelli nel file di intestazione /usr/include/math.h e ho trovato un'alta corrispondenza. Mi sembra possibile scrivere un programma basato su questo. Analizzare la colonna finale del comando readelf in alto e fare un grep per tutti i file .h in/usr/include. Non l'ho preso così lontano, però.

Dopo aver eseguito alcuni esperimenti relativi alla mia risposta, ho scoperto che il comando sed potrebbe probabilmente essere ulteriormente rifinito per le vostre esigenze. Quando ho usato readelf su libcurl.a, anche le funzioni non globali (quindi, quelle che non devono essere incluse nei file di intestazione) vengono emesse.