On Linux, I have ac shared library that depends on other libs. LD_LIBRARY_PATH is properly set to allow the linker to load all the libraries. When I do:
libgidcwf = ctypes.cdll.LoadLibrary(libidcwf_path)
I get the following 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
It seems that LD_LIBRARY_PATH has no effect here. Is there a way to have these dependency library "loadable" ?
Thanks in advance for the help.
It would seem that libwav.so does not declare it's dependency on the library defining ODBCGeneralQuery. Try running ldd path-to-my-lib/libwav.so
and see if there's something missing. If this is a shared library that you are building you should add -llibname
to the linking command (the one that is something like gcc -shared -o libwav.so ao bo co
) for each library that the library's code uses. Any other libraries referenced by the original shared library in this way should automatically be loaded as well.
You should use RTLD_GLOBAL . I have a mixed platform system, so my code looks something like this:
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)
When you compile the shared object, be sure to put all the -lsomething
at the end of the string command. For me it solved the problem.
I had the same problem. Two things were required in order to solve it:
RTLD_GLOBAL
as other users said ODBCGeneralQuery
is defined in lets say libIDCodbc
, you need first run this line: ctypes.CDLL("libIDCodbc.so", mode = ctypes.RTLD_GLOBAL)
I found I had to use RTLD_LAZY
due to an undefined symbol that was not linked because it was not being used. Since there is no ctypes.RTLD_LAZY
in my ctypes, I had to use:
ctypes.CDLL(libidcwf_path, mode=1)
I found this mode by inspecting /usr/include/bits/dlfcn.h
which is probably not standard. Hat tip to this 2006 thread on the ctypes mailing list.
Based on Walter Nissen's answer above, you can modify the code to be:
import os
ctypes.CDLL(libidcwf_path, mode=os.RTLD_LAZY)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.