2010-02-24 20 views
18

En Linux, tengo una biblioteca compartida c que depende de otras librerías. LD_LIBRARY_PATH está configurado correctamente para permitir que el enlazador cargue todas las bibliotecas. Cuando hago:ctypes cargando una biblioteca compartida c que tiene dependencias

libgidcwf = ctypes.cdll.LoadLibrary(libidcwf_path) 

me sale 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 ningún efecto aquí. ¿Hay alguna manera de tener esta biblioteca de dependencias "cargable"?

Gracias de antemano por la ayuda.

+0

¿En qué SO estás? Ver http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html - es 'SHLIB_PATH' en HpUx,' LIBPATH' en Aix, 'DYLD_lotsofthings' en Mac ... la semántica también difiere sutilmente. Incluso si es Linux, los pls aclaran la versión y etiquetan su Q apropiadamente, ¡gracias! –

+1

Estoy en Linux, así que uso LD_LIBRARY_PATH pero no parece ser usado por ctypes – zoobert

Respuesta

15

Parece que libwav.so no declara su dependencia de la biblioteca que define ODBCGeneralQuery. Intente ejecutar ldd path-to-my-lib/libwav.so y vea si falta algo. Si se trata de una biblioteca compartida que está creando, debe agregar -llibname al comando de enlace (el que es algo así como gcc -shared -o libwav.so a.o b.o c.o) para cada biblioteca que utiliza el código de la biblioteca. Cualquier otra biblioteca referenciada por la biblioteca compartida original de esta manera también debería cargarse automáticamente.

+0

. Agradecería mucho que me explicara "algo que falta". Corro ldd en mi .so, pero ¿qué se supone que debo ver? – Bex

+0

Supongo que mi significado no está claro. Quise decir que ldd mostrará las bibliotecas que las referencias libwav.so y que deben ser inspeccionadas para ver si hay una biblioteca que debe aparecer pero no lo es. –

+0

Muchas gracias por aclarar esta respuesta de hace cuatro años. Encuentro que la salida de 'ldd' es un poco confusa, pero tu respuesta ayuda a aclararla. Gracias. – Bex

4

Debe usar RTLD_GLOBAL. Tengo un sistema de plataforma mixta, por lo que mi código es como la siguiente:

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) 
5

Cuando se compila el objeto compartido, asegúrese de poner toda la -lsomething al final de la cadena de comando. Para mí, resolvió el problema.

3

Tuve el mismo problema. Dos cosas fueron requeridos con el fin de resolverlo:

  1. uso del RTLD_GLOBAL como otros usuarios dijeron
  2. tiene que cargar todas las bibliotecas que se utiliza por su biblioteca. Así que si ODBCGeneralQuery se define en digamos libIDCodbc, primero se necesita ejecutar esta línea:

ctypes.CDLL("libIDCodbc.so", mode = ctypes.RTLD_GLOBAL)

2

me encontré con que tenía que usar RTLD_LAZY debido a un símbolo indefinido que no estaba vinculado, ya que no estaba siendo utilizada . Puesto que no hay ctypes.RTLD_LAZY en mis ctypes, tuve que usar:

ctypes.CDLL(libidcwf_path, mode=1) 

yo encontramos este modo mediante la inspección de /usr/include/bits/dlfcn.h que probablemente no es estándar. Sombrero de punta a este 2006 thread en la lista de correo de ctypes.

Cuestiones relacionadas