Saltar al contenido

Cambiar LD_LIBRARY_PATH en tiempo de ejecución para ctypes

Agradeceríamos tu ayuda para compartir nuestros tutoriales acerca de las ciencias de la computación.

Solución:

En el momento en que se ejecuta un programa como Python, el cargador dinámico (ld.so.1 o algo similar) ya ha leído LD_LIBRARY_PATH y no notará ningún cambio a partir de entonces. Entonces, a menos que el propio software de Python evalúe LD_LIBRARY_PATH y lo use para crear el posible nombre de ruta de la biblioteca para dlopen() o una función equivalente para usar, establecer la variable en el script no tendrá ningún efecto.

Dado que dice que no funciona, parece plausible suponer que Python no compila ni prueba todos los nombres de biblioteca posibles; probablemente dependa solo de LD_LIBRARY_PATH.

Incluso si proporciona una ruta completa a CDLL o cdll.LoadLibrary(), es posible que aún deba configurar LD_LIBRARY_PATH antes de invocar a Python. Si la biblioteca compartida que carga se refiere explícitamente a otra biblioteca compartida y no se establece “rpath” en el .so para esa biblioteca, entonces no se encontrará, incluso si ya se ha cargado. Un rpath en una biblioteca especifica una ruta de búsqueda que se usará para buscar otras bibliotecas que necesita esa biblioteca

Por ejemplo, tengo un caso de un conjunto de bibliotecas de terceros interdependientes que no produje. b.so referencias a.so. Incluso si cargo también por adelantado:

ctypes.cdll.LoadLibrary('/abs/path/to/a.so')
ctypes.cdll.LoadLibrary('/abs/path/to/b.so')

Recibo un error en la segunda carga, porque b.so se refiere simplemente a ‘a.so’, sin un rpath, por lo que b.so no sabe que ese es el a.so correcto. Así que tengo que configurar LD_LIBRARY_PATH por adelantado para incluir ‘/abs/path/to’.

Para evitar tener que configurar LD_LIBRARY_PATH, modifique la entrada rpath en los archivos .so. En Linux, encontré dos utilidades que hacen esto: chrpath y patchelf. chrpath está disponible en los repositorios de Ubuntu. No puede cambiar el rpath en .so’s que nunca tuvo uno. patchelf es más flexible.

A CDLL se le puede pasar un nombre de ruta completo, por ejemplo, estoy usando lo siguiente en uno de mis scripts donde .so está en el mismo directorio que el script de python.

import os
path = os.path.dirname(os.path.realpath(__file__))
dll = CDLL("%s/iface.so"%path)

En su caso, lo siguiente debería ser suficiente.

from ctypes import *
lib = CDLL("/home/starlon/Projects/pyCFA635/lib/libevaluator.so")

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *