2010-02-24 21 views
18

Trên Linux, tôi có thư viện được chia sẻ c phụ thuộc vào các thư viện khác. LD_LIBRARY_PATH được đặt đúng để cho phép trình liên kết tải tất cả các thư viện. Khi tôi làm:ctypes đang tải thư viện chia sẻ c có phụ thuộc

libgidcwf = ctypes.cdll.LoadLibrary(libidcwf_path) 

tôi nhận được lỗi sau:

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 

Dường như LD_LIBRARY_PATH mà không có tác dụng ở đây. Có cách nào để có thư viện phụ thuộc "có thể tải" này không?

Cảm ơn bạn đã trợ giúp.

+0

Bạn đang sử dụng hệ điều hành nào? Xem http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html - đó là 'SHLIB_PATH' trong HpUx,' LIBPATH' trong Aix, 'DYLD_lotsofthings' trên Mac ... ngữ nghĩa cũng khác nhau một cách tinh tế. Ngay cả khi Linux, hãy làm rõ phiên bản và gắn thẻ Q của bạn một cách thích hợp, cảm ơn! –

+1

Tôi đang sử dụng Linux vì vậy tôi sử dụng LD_LIBRARY_PATH nhưng dường như không được sử dụng bởi ctypes – zoobert

Trả lời

15

Dường như libwav.so không khai báo sự phụ thuộc của nó vào thư viện xác định ODBCGeneralQuery. Hãy thử chạy ldd path-to-my-lib/libwav.so và xem có thiếu thứ gì không. Nếu đây là thư viện được chia sẻ mà bạn đang xây dựng, bạn nên thêm -llibname vào lệnh liên kết (lệnh giống như gcc -shared -o libwav.so a.o b.o c.o) cho mỗi thư viện mà mã của thư viện sử dụng. Bất kỳ thư viện nào khác được tham chiếu bởi thư viện được chia sẻ ban đầu theo cách này cũng sẽ tự động được tải.

+0

Tôi sẽ đánh giá rất cao nếu bạn sẽ giải thích về "điều gì đó bị thiếu". Tôi chạy ldd trên của tôi .so - nhưng những gì tôi phải xem? – Bex

+0

Tôi đoán ý nghĩa của tôi là không rõ ràng. Tôi có nghĩa là ldd sẽ hiển thị các thư viện mà libwav.so tài liệu tham khảo và cần được kiểm tra để xem nếu có một thư viện mà nên được liệt kê nhưng không phải là. –

+0

Cảm ơn bạn rất nhiều vì đã làm rõ câu trả lời bốn tuổi này. Tôi tìm thấy đầu ra từ 'ldd' một chút khó hiểu, nhưng câu trả lời của bạn sẽ giúp làm rõ nó. Cảm ơn. – Bex

4

Bạn nên sử dụng RTLD_GLOBAL. Tôi có một hệ thống nền tảng khác nhau, do đó, mã của tôi trông giống như sau:

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

Khi bạn biên dịch các đối tượng chia sẻ, hãy chắc chắn để đặt tất cả các -lsomething vào cuối lệnh chuỗi. Đối với tôi, nó giải quyết được vấn đề.

3

Tôi gặp vấn đề tương tự. Hai điều đã được yêu cầu để giải quyết nó:

  1. sử dụng các RTLD_GLOBAL như những người dùng khác cho biết
  2. Bạn cần phải nạp mỗi thư viện được sử dụng bởi thư viện của bạn. Vì vậy, nếu ODBCGeneralQuery được định nghĩa trong phép nói libIDCodbc, bạn cần đầu tiên chạy dòng này:

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

2

tôi thấy tôi đã phải sử dụng RTLD_LAZY do một biểu tượng không xác định mà không được liên kết bởi vì nó đã không được sử dụng . Vì không có ctypes.RTLD_LAZY trong ctypes của tôi, tôi đã phải sử dụng:

ctypes.CDLL(libidcwf_path, mode=1) 

tôi thấy chế độ này bằng cách kiểm tra /usr/include/bits/dlfcn.h mà có lẽ không chuẩn. Mẹo vặt cho năm 2006 thread này trên danh sách gửi thư của ctypes.

Các vấn đề liên quan