C++ Come ottenere un nome file (e percorso) del modulo .so in esecuzione in Unix?C++ Come ottenere un nome file (e percorso) del modulo .so in esecuzione in Unix
Qualcosa di simile a GetModuleFileName su Windows.
C++ Come ottenere un nome file (e percorso) del modulo .so in esecuzione in Unix?C++ Come ottenere un nome file (e percorso) del modulo .so in esecuzione in Unix
Qualcosa di simile a GetModuleFileName su Windows.
Anche se non è un'interfaccia standard POSIX, la funzione dladdr()
è disponibile su molti sistemi compreso Linux, Solaris, Darwin/Mac OS X, FreeBSD, HP-UX e IRIX. Questa funzione accetta un indirizzo, ad esempio un puntatore a una funzione statica all'interno del modulo (se trasmesso a void *
) e riempie una struttura Dl_info
con informazioni che includono il nome percorso dell'oggetto condiviso che contiene quell'indirizzo (nello dli_fname
membro).
Se potessi ancora votare, darei un +1 per rispondere alla domanda originale . –
Ora che posso votare, +1. –
BTW ha trovato risposta su SO (è stato chiesto 5 mesi fa): http://stackoverflow.com/questions/1681060/library-path-when-dynamically-loaded – Steve
Sfortunatamente, non c'è modo di farlo utilizzando UNIX o POSIX. Se è necessario utilizzarlo per cercare una sorta di dati, è necessario utilizzare la variabile di ambiente $ PATH e cercare i dati in un percorso relativo a ciascuna voce in $ PATH. Ad esempio, non è raro per memorizzare i file binari in " installdir/bin" per un po 'directory di installazione "installdir" e per memorizzare i dati associati a " installdir/share/ nome_del_programma" per un po' directory di installazione e qualche programma chiamato "nome_di_programma". In tal caso, guardare "../share/ name_of_program/ name_of_resource_file" relativo a ciascuna voce in getenv ("PATH") è un buon metodo per cercare le risorse. Un'altra cosa che si potrebbe fare è consentire che le informazioni necessarie siano fornite sulla riga di comando o in qualche file di configurazione, e solo eseguire la ricerca se necessario come opzione di fallback.
Modifica
Ora che avete dichiarato la vostra logica di questo, vorrei consigliare di utilizzare semplicemente la classe QSettings da Qt per il vostro informazioni di configurazione, in quanto utilizza il meccanismo nativo preferito per ciascuna piattaforma (il Registro di sistema su Windows, un file PLIST su Mac OS X, il database Gnome GConf su Linux). Potresti dare un'occhiata al mio C++ Project Template poiché usa Qt per fare proprio questo, e fornisce semplici opzioni a riga di comando per modificare facilmente le impostazioni di configurazione ("--prefset", "--prefget" e "--preflist" manipolare QSettings).
Detto questo, se è assolutamente necessario utilizzare un file di configurazione XML del proprio invece di utilizzare il meccanismo nativo preferito, vi consiglio vivamente di posizionare la configurazione a livello di sistema in " installdir/etc" pur ponendo la vostra biblioteca in " installdir/lib" per alcune directory di installazione "installdir", poiché quella è la posizione tipica per i file di configurazione sui sistemi UNIX e " installdir/lib" deve essere utilizzato SOLO per i file di libreria, non per i file di configurazione e altri errata. Ti suggerisco di inserire una versione specifica del file di configurazione in "$ XDG_CONFIG_HOME" (se è definita) o in "$ HOME/.config" (dove "$ HOME" è la cartella home dell'utente).
Durante la ricerca del file di configurazione a livello di sistema, si consiglia di cercare in $ XDG_CONFIG_DIRS se è definito; se non è definito, tornare a "/ etc/xdg" o cercare "../etc/name_of_your_program.conf.xml" relativo a "$ PATH" e possibilmente anche relativo a "$ LD_LIBRARY_PATH", " $ DYLD_LIBRARY_PATH "," $ DYLD_FALLBACK_LIBRARY_PATH "), il contenuto di" /etc/ld.so.conf "se esiste, e il contenuto di" /etc/ld.so.conf.d/*.conf "se quei file esiste, interrompendo la ricerca non appena si incontra il primo file di configurazione valido sarà un approccio ragionevole.
Il credito va a Roger per indicare lo XDG Basedir Spec e per le sue eccellenti critiche costruttive.
@ Roger, grazie ancora. Hai ragione di nuovo. Forse dovresti prendere in considerazione la possibilità di scrivere una risposta completa ... probabilmente faresti un lavoro migliore, e ti svaluterò. In ogni caso, le tue critiche costruttive sono abbastanza utili. Grazie. –
Prego, ma non posso rispondere perché, anche se è ciò che vuole veramente, non risponde a quello che ha effettivamente chiesto. (@Steve: sei libero di cambiare la domanda in "Come trovo la configurazione per la mia biblioteca/programma?" Però ..: P) –
Possibili soluzioni:
/proc/{PID}/mmap
per l'elenco delle librerie condivise. Dove {PID} è il processo pid (puoi farlo usando getpid()
).ldd
per il file binario del programma (memorizzato in argv[0]
).ldd
da uClibc
come ottenere l'elenco di librerie condivise da un file binario elfo.
Una volta ottenuto il percorso, cosa pensi di fare con esso? –
in pratica quello che voglio fare è rilasciare il file di configurazione nella stessa cartella del mio file .so, quindi ho bisogno di ottenere un percorso completo per il file di configurazione e quindi di passare questo nome completo al parser di xml config. – Steve
È normale e consigliato utilizzare un [percorso separato per i file di configurazione] (http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html), quindi non è necessario. –