ś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;
}
Author: jldupont, 2009-11-05

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 i dli_saddr są ustawione na NULL.

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ą.

 17
Author: Jay Conrod,
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