求助:python需要加载多个.so文件的问题。

zhangxian_engineer 2015-06-23 05:37:30
我这边有3个.so文件,因为.so文件有依赖关系,所以需要顺序加载:1、libhpr.so 2、libhlog.so 3、libHcsSdk.so

我的实现方法:
cdll.LoadLibrary("./libhpr.so")
cdll.LoadLibrary("./libhlog.so")
lib = cdll.LoadLibrary("./libHcsSdk.so")

但发现最后一个cdll.LoadLibrary("./libHcsSdk.so")还是加载失败,找不到某个函数:
OSError: ./libHcsSdk.so: undefined symbol: hlog_print

这个hlog_print 是在前面的libhlog.so里面的接口函数。

我用ctypes需要怎么样调用呢?
...全文
1796 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
panghuhu250 2015-06-23
  • 打赏
  • 举报
回复
这是因为cdll.LoadLibrary("./libHcsSdk.so")看不到你前面加载的so文件. 有两个办法解决: 1. 使用RTLD_GLOBAL模式加载所需要的so.

CDLL("./libhpr.so", mode=ctypes.RTLD_GLOBAL)
CDLL("./libhlog.so", mode=ctypes.RTLD_GLOBAL)
lib = cdll.LoadLibrary("./libHcsSdk.so")
2. 如果你自己可以控制这几个so文件的编译的话, 可以把so之间的依赖关系编译进去, ctypes会自动加载libHcsSdk.so依赖的其它库. 办法是在生成so文件时, 用-l选项加入所有需要的库. 例如, 下面的例子中, useall依赖于sq和dball.

/tmp/sotest/ gcc -shared -Wl,-soname,libuseall.so -o libuseall.so useall.o -lc -L. -lsq -ldball

/tmp/sotest/ gcc -shared -Wl,-soname,libuseall.so.1 -o libuseall.so.1 useall.o -lc           

/tmp/sotest/ ls *
all.h    dball.o     libdball.so  libuseall.so    sq.c  sq.so.1   useall.o
dball.c  dball.so.1  libsq.so     libuseall.so.1  sq.o  useall.c

/tmp/sotest/ ldd libuseall.so.1  # libuseall.so.1依赖的库, 只有一些系统的库
        linux-vdso.so.1 (0x00007ffdbafe0000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1f0b78d000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f1f0bd60000)

/tmp/sotest/ ldd libuseall.so # libuseall.so依赖于libsq.so和libbdall.so
        linux-vdso.so.1 (0x00007ffdc5975000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc7440ae000)
        libsq.so (0x00007fc743ead000)
        libdball.so (0x00007fc743cab000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fc744681000)
libuseall.so可以用ctypes直接加载. libuseall.so.1不行. 下面是用python ctypes加载的例子:

/tmp/sotest/ LD_LIBRARY_PATH='.' python
Python 2.7.9 (default, Apr 29 2015, 18:34:06) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> lib = ctypes.CDLL('libuseall.so.1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/ctypes/__init__.py", line 365, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: ./libuseall.so.1: undefined symbol: mydouble
>>> lib = ctypes.CDLL('libuseall.so')
>>> lib.doublesq(10)
200
>>> ctypes.CDLL('libdball.so')
<CDLL 'libdball.so', handle b0d980 at 7f0695eea3d0>
>>> lib2 = ctypes.CDLL('libuseall.so.1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/ctypes/__init__.py", line 365, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: ./libuseall.so.1: undefined symbol: mydouble
>>> ctypes.CDLL('libdball.so', ctypes.RTLD_GLOBAL)
<CDLL 'libdball.so', handle b0d980 at 7f0695eea0d0>
>>> lib2 = ctypes.CDLL('libuseall.so.1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/ctypes/__init__.py", line 365, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: ./libuseall.so.1: undefined symbol: mysquare  
# 使用ctypes.RTLD_GLOBAL加载libdball.so后, mydouble没问题了
>>> ctypes.CDLL('libsq.so', ctypes.RTLD_GLOBAL)
<CDLL 'libsq.so', handle b0d4d0 at 7f0695eea510>
>>> lib2 = ctypes.CDLL('libuseall.so.1')
>>> lib2.doublesq(20)
800
>>> 

longxiahi 2015-06-23
  • 打赏
  • 举报
回复
是不是加载以后就释放了。 cdll.LoadLibrary("./libhpr.so") cdll.LoadLibrary("./libhlog.so")

37,739

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • WuKongSecurity@BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧