2010-02-24 11 views
18

W systemie Linux mam c współużytkowaną bibliotekę, która zależy od innych bibliotek. LD_LIBRARY_PATH jest poprawnie ustawiony, aby umożliwić linkerowi załadowanie wszystkich bibliotek. Kiedy zrobić:ctypes ładowanie biblioteki współużytkowanej c, która ma zależności

libgidcwf = ctypes.cdll.LoadLibrary(libidcwf_path) 

pojawia się następujący błąd:

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 

Wydaje się, że nie ma wpływu LD_LIBRARY_PATH tutaj. Czy istnieje sposób, aby te biblioteki zależności były "ładowalne"?

Z góry dziękujemy za pomoc.

+0

W jakim systemie operacyjnym jesteś? Zobacz http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html - to 'SHLIB_PATH' w HpUx,' LIBPATH' w Aix, 'DYLD_lotsofthings' na Macu ... semantyki również różnią się subtelnie. Nawet jeśli Linux, pls wyjaśnić wersję i oznacz swój Q odpowiednio, dziękuję! –

+1

Jestem na Linuksie, więc używam LD_LIBRARY_PATH, ale nie wydaje się być używane przez ctypes – zoobert

Odpowiedz

15

Wygląda na to, że libwav.so nie deklaruje zależności od biblioteki definiującej ODBCGeneralQuery. Spróbuj uruchomić ldd path-to-my-lib/libwav.so i sprawdzić, czy czegoś brakuje. Jeśli jest to biblioteka współdzielona, ​​którą budujesz, dodaj komendę łączenia (gcc -shared -o libwav.so a.o b.o c.o) do każdej biblioteki używanej przez bibliotekę. Wszelkie inne biblioteki, do których odwołuje się w ten sposób oryginalna biblioteka współdzielona, ​​powinny również zostać automatycznie załadowane.

+0

Byłbym bardzo wdzięczny, gdybyś opracował "coś brakuje". Prowadzę ldd na moim .so - ale co mam zobaczyć? – Bex

+0

Myślę, że moje znaczenie jest niejasne. Chodzi mi o to, że ldd pokaże biblioteki, do których odwołuje się libwav.so i które powinny zostać sprawdzone, aby sprawdzić, czy istnieje biblioteka, która powinna być wymieniona, ale nie jest. –

+0

Dziękuję bardzo za wyjaśnienie tej czteroletniej odpowiedzi. Dane wyjściowe z 'ldd' są nieco mylące, ale twoja odpowiedź pomaga je wyjaśnić. Dzięki. – Bex

4

Powinieneś użyć RTLD_GLOBAL. Mam mieszane systemu platformy, więc mój kod wygląda mniej więcej tak:

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

Podczas kompilowania obiekt udostępniony, należy umieścić wszystkie -lsomething na końcu polecenia strun. Dla mnie to rozwiązało problem.

3

Miałem ten sam problem. Dwie rzeczy były konieczne w celu rozwiązania go:

  1. Użyj RTLD_GLOBAL innych użytkowników powiedział
  2. Trzeba załadować każdą bibliotekę, która jest używana przez biblioteki. Więc jeśli ODBCGeneralQuery jest zdefiniowana w powiedzmy libIDCodbc, trzeba najpierw uruchomić ten wiersz:

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

2

znalazłem musiałem użyć RTLD_LAZY powodu nieokreślonej symbolu, który nie został powiązany ponieważ nie był używany . Ponieważ nie ma ctypes.RTLD_LAZY w moich ctypes, musiałem użyć:

ctypes.CDLL(libidcwf_path, mode=1) 

znalazłem ten tryb, sprawdzając /usr/include/bits/dlfcn.h który prawdopodobnie nie jest standardem. Koniec końcówki do tego 2006 thread na liście mailingowej ctypes.

Powiązane problemy