mejores - modulos estandar en python
ctypes cargando una biblioteca compartida que tiene dependencias (5)
Cuando compile el objeto compartido, asegúrese de poner todo el elemento -lsomething
final del comando de cadena. Para mi resolvió el problema.
En Linux, tengo una biblioteca compartida de CA que depende de otras librerías. LD_LIBRARY_PATH está configurado correctamente para permitir que el vinculador cargue todas las bibliotecas. Cuando lo hago:
libgidcwf = ctypes.cdll.LoadLibrary(libidcwf_path)
Obtuve el siguiente error:
Traceback (most recent call last):
File "libwfm_test.py", line 12, in <module>
libgidcwf = ctypes.cdll.LoadLibrary(libidcwf_path)
File "/usr/lib/python2.5/ctypes/__init__.py", line 431, in LoadLibrary
return self._dlltype(name)
File "/usr/lib/python2.5/ctypes/__init__.py", line 348, in __init__
self._handle = _dlopen(self._name, mode)
OSError: path-to-my-lib/libwav.so: undefined symbol: ODBCGeneralQuery
Parece que LD_LIBRARY_PATH no tiene efecto aquí. ¿Hay una manera de tener estas bibliotecas de dependencia "cargables"?
Gracias de antemano por la ayuda.
Debe utilizar RTLD_GLOBAL . Tengo un sistema de plataforma mixta, por lo que mi código se parece a esto:
import numpy, ctypes
try:
if "Linux" in esmfos:
_ESMF = ctypes.CDLL(libsdir+''/libesmf.so'',mode=ctypes.RTLD_GLOBAL)
else:
_ESMF = numpy.ctypeslib.load_library(''libesmf'',libsdir)
except:
traceback.print_exc(file=sys.stdout)
sys.exit(ESMP_ERROR_SHAREDLIB)
Descubrí que tenía que usar RTLD_LAZY
debido a un símbolo no definido que no estaba vinculado porque no se estaba usando. Como no hay ctypes.RTLD_LAZY
en mis ctypes, tuve que usar:
ctypes.CDLL(libidcwf_path, mode=1)
Encontré este modo inspeccionando /usr/include/bits/dlfcn.h
que probablemente no sea estándar. Sugerencia de sombrero para este thread 2006 en la lista de correo de ctypes.
Parece que libwav.so no declara que depende de la biblioteca que define ODBCGeneralQuery. Intente ejecutar ldd path-to-my-lib/libwav.so
y vea si falta algo. Si esta es una biblioteca compartida que está creando, debe agregar -llibname
al comando de enlace (el que es algo como gcc -shared -o libwav.so ao bo co
) para cada biblioteca que usa el código de la biblioteca. Las demás bibliotecas a las que la biblioteca compartida original hace referencia de esta manera también deben cargarse automáticamente.
Yo tuve el mismo problema. Se requirieron dos cosas para resolverlo:
- usa el
RTLD_GLOBAL
comoRTLD_GLOBAL
otros usuarios - Debe cargar todas las bibliotecas que utiliza su biblioteca. Entonces, si
ODBCGeneralQuery
está definido en digamoslibIDCodbc
, primero necesita ejecutar esta línea:
ctypes.CDLL("libIDCodbc.so", mode = ctypes.RTLD_GLOBAL)