2010-04-09 10 views
5

C++ ¿Cómo obtener un nombre de archivo (y ruta) del módulo .so en ejecución en Unix?C++ Cómo obtener un nombre de archivo (y ruta) del módulo .so en ejecución en Unix

Algo similar a GetModuleFileName en Windows.

+2

Una vez que obtenga el camino, ¿qué piensa hacer con él? –

+0

básicamente lo que quiero hacer es soltar el archivo de configuración en la misma carpeta que mi archivo .so, luego necesito obtener una ruta completa al archivo de configuración y luego pasar este nombre completo al analizador de configuración xml. – Steve

+2

Es común y se recomienda utilizar una [ruta de acceso independiente para los archivos de configuración] (http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html), por lo que no es necesario. –

Respuesta

6

Aunque no es una interfaz estándar POSIX, la función de dladdr() está disponible en muchos sistemas, incluyendo Linux, Solaris, Darwin/Mac OS X, FreeBSD, HP-UX, y IRIX. Esta función toma una dirección, que podría ser un puntero a una función estática dentro del módulo, por ejemplo (si se envía a void *), y rellena una estructura Dl_info con información que incluye el nombre de ruta del objeto compartido que contiene esa dirección (en el dli_fname miembro).

+0

Si aún pudiera votar, daría un +1 por responder la pregunta original . –

+0

Ahora que puedo votar, +1. –

+0

BTW encontró respuesta en SO (se solicitó hace 5 meses): http://stackoverflow.com/questions/1681060/library-path-when-dynamically-loaded – Steve

2

Desafortunadamente, no hay forma de hacerlo con UNIX o POSIX. Si necesita usarlo para buscar algún tipo de datos, debe usar la variable de entorno $ PATH y buscar los datos en una ruta relativa a cada entrada en $ PATH. Por ejemplo, no es raro para almacenar binarios en " dirinstal/bin" para algunos "dirinstal" directorio de instalación y para almacenar los datos asociados en " dirinstal/share/ name_of_program" por algún directorio de instalación y algunos programas llamado "nombre_de_programa". Si ese es el caso, entonces mirando "../share/ name_of_program/ name_of_resource_file" relativo a cada entrada en getenv ("PATH") es una buena forma de buscar recursos. Otra cosa que podría hacer es permitir que se proporcione la información necesaria en la línea de comandos o en algún archivo de configuración, y solo realizar la búsqueda si es necesario como una opción alternativa.

Editar
Ahora que ha declarado su razón de esto, yo le aconsejaría usar simplemente la clase QSettings de Qt para la información de configuración, ya que utiliza el mecanismo nativo preferido para cada plataforma (el registro en Windows, un archivo PLIST en Mac OS X, la base de datos Gnome GConf en Linux). Es posible que desee echar un vistazo a mi C++ Project Template, ya que utiliza Qt para hacer esto, y proporciona opciones simples de línea de comandos para modificar fácilmente la configuración ("--prefset", "--prefget" y "--preflist" manipular QSettings).

Dicho esto, si necesita usar un archivo de configuración XML propio en lugar de usar el mecanismo nativo preferido, le recomiendo encarecidamente que coloque la configuración de todo el sistema en " installdir/etc" mientras coloca su biblioteca en " installdir/lib" para algún directorio de instalación "installdir", ya que es el lugar típico para archivos de configuración en sistemas UNIX, y " installdir/lib" ÚNICAMENTE se debe usar para archivos de biblioteca, no para archivos de configuración y otra errata Sugiero que coloque una versión específica del usuario del archivo de configuración en "$ XDG_CONFIG_HOME" (si está definido) o en "$ HOME/.config" (donde "$ HOME" es la carpeta de inicio del usuario).

Al buscar el archivo de configuración de todo el sistema, le recomendaría que busque dentro de $ XDG_CONFIG_DIRS si está definido; si no está definido, vuelva a "/ etc/xdg" o busque "../etc/name_of_your_program.conf.xml" en relación con "$ PATH" y posiblemente también en relación con "$ LD_LIBRARY_PATH", " $ DYLD_LIBRARY_PATH "," $ DYLD_FALLBACK_LIBRARY_PATH "), el contenido de" /etc/ld.so.conf "si existe, y el contenido de" /etc/ld.so.conf.d/*.conf "si esos archivos existir, detener su búsqueda tan pronto como se encuentre con el primer archivo de configuración válido sería un enfoque sensato.

El crédito va a Roger por señalar el XDG Basedir Spec y por sus excelentes críticas constructivas.

+0

@Roger, gracias de nuevo. Tienes razón de nuevo. Tal vez deberías considerar escribir una respuesta completa ... probablemente harías un mejor trabajo, y te volvería a votar. En cualquier caso, tus críticas constructivas son bastante útiles. Gracias. –

+0

De nada, pero no puedo responder porque, aunque es lo que realmente quiere, no responde a lo que realmente le preguntó. (@Steve: Puedes cambiar la pregunta a "¿Cómo encuentro la configuración de mi biblioteca/programa?" Aunque ...: P) –

0

soluciones posibles:

  • se puede leer el archivo /proc/{PID}/mmap de la lista de bibliotecas compartidas. Donde {PID} es el proceso pid (puede obtenerlo usando getpid()).
  • Llame a la herramienta de línea de comandos ldd para el archivo binario del programa (almacenado en argv[0]).
  • Si escribe una solución desde cero, eche un vistazo a ldd mandatos código fuente desde uClibc cómo obtener la lista de bibliotecas compartidas de un archivo binario elf.
Cuestiones relacionadas