ścieżka biblioteki po załadowaniu dynamicznym?
Jak mogę pobrać ścieżkę udostępnionej biblioteki z samej biblioteki?
Innymi słowy, powiedzmy, że biblioteka X jest ładowana za pomocą dlopen()
, Jak mogę uzyskać dostęp do ścieżki, która została użyta do załadowania wspomnianej biblioteki z samej biblioteki?
Zauważ, że nie mogę pozwolić, aby agent, który załadował bibliotekę, podał mi ten parametr.
Zaktualizowano: oto sposób, który działa ze zmiennymi statycznymi:
std::string wdir;
namespace {
class dynamic_library_load_unload_handler {
public:
dynamic_library_load_unload_handler(){
Dl_info dl_info;
dladdr((void *) NP_Initialize, &dl_info);
std::string path(dl_info.dli_fname);
wdir = path.substr( 0, path.find_last_of( '/' ) +1 );
}
~dynamic_library_load_unload_handler(){
// Code to execute when the library is unloaded
}
} dynamic_library_load_unload_handler_hook;
}
1 answers
Dynamiczny linker faktycznie przeszukuje kilka miejsc, aby znaleźć każdą bibliotekę dynamiczną. Należą do nich (od człowieka ld.so):
- ścieżki podane przez zmienną środowiskową
LD_LIBRARY_PATH
- ścieżki do pliku binarnego ładują bibliotekę pod wpisem
DT_RUNPATH
- plik cache / etc / ld. so. cache
- / lib I / usr / lib
Jeśli chcesz uzyskać ścieżkę do określonej biblioteki współdzielonej, polecam funkcję dladdr
. Ze strony man:
Funkcja dladdr() pobiera wskaźnik funkcji i próbuje rozwiązać nazwa i plik, w którym się znajduje. Informacje są przechowywane w
Dl_info
struktura:typedef struct { const char *dli_fname; /* Pathname of shared object that contains address */ void *dli_fbase; /* Address at which shared object is loaded */ const char *dli_sname; /* Name of nearest symbol with address lower than addr */ void *dli_saddr; /* Exact address of symbol named in dli_sname */ } Dl_info;
Jeśli nie znaleziono żadnego symbolu pasującego do addr, to
dli_sname
idli_saddr
są ustawione naNULL
.
dladdr()
zwraca 0 W przypadku błędu i niezerowe w przypadku sukcesu.
Więc po prostu dajesz mu wskaźnik funkcji, a to da Ci nazwę pliku, który go dostarcza i kilka innych informacje. Na przykład, możesz mieć konstruktor w bibliotece, który sam to wywoła, aby dowiedzieć się pełnej ścieżki biblioteki:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
__attribute__((constructor))
void on_load(void) {
Dl_info dl_info;
dladdr((void *)on_load, &dl_info);
fprintf(stderr, "module %s loaded\n", dl_info.dli_fname);
}
Ta funkcja działa również na OS X z tą samą semantyką.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-05 15:32:08