求助! Python 如何调用 C 语言.SO 动态库(并且被调用的动态库还依赖其它的动态库) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
wsds
V2EX    Python

求助! Python 如何调用 C 语言.SO 动态库(并且被调用的动态库还依赖其它的动态库)

  •  
  •   wsds 2018-05-28 11:28:51 +08:00 7543 次点击
    这是一个创建于 2774 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近要做 SDK 测试,SDK 是由 C 语言封装成的,函数封装在了 .so动态库中,而且该动态库还依赖其他的第三方动态库,不知道该怎么调用,求助各位大神,给个 demo

    ps: linux平台的库

    #call_c.py import ctypes from ctypes import * ll = ctypes.cdll.LoadLibrary lib = ll("./libIFaceRecSDK.so") 

    单独调用就大概是上面这样子了,但 libIFaceRecSDK.so 这个动态库还依赖其他库,且带有头文件时,我该怎么调用啊??你们看,这个库还依赖以下的这多么的库,还有头文件!!求救!

    2pLxlT.png

    第 1 条附言    2018-05-28 14:55:16 +08:00

    用了楼下老铁们推荐的cffi模块,调用的时候,还是报错,不知道咋回事

    2ps98r.png

    24 条回复    2018-05-29 13:14:36 +08:00
    mashiro233
        1
    mashiro233  
       2018-05-28 11:47:56 +08:00
    遇到这种情况,我的解决方法就是要么自己封装一个 C 模块给 py,要么 FFI。前者偏向调用复杂模块的时候,后者偏向调用简单模块。
    另外这个依赖和你没多少关系,系统或者 libffi 会帮你解决。

    给个 CFFI 参考链接。
    https://eli.thegreenplace.net/2013/03/09/python-ffi-with-ctypes-and-cffi/
    wsds
        2
    wsds  
    OP
       2018-05-28 11:57:12 +08:00
    @mashiro233
    /尴尬,不会 C 语言,现在手里就一份 SDK 内置函数文档,还有些库文件,头文件,我要做的就是用 python 调 SDK 中的这些方法;
    我看一下这个 FFI,谢谢哈
    wellsc
        3
    wellsc  
       2018-05-28 12:03:39 +08:00 via iPhone
    Cffi 了解一下
    wsds
        4
    wsds  
    OP
       2018-05-28 17:40:38 +08:00
    @mashiro233 调不通啊,报错
    qieqie
        5
    qieqie  
       2018-05-28 18:33:50 +08:00
    你只需要知道返回值和参数列表的类型,不需要头文件。
    ld-linux.so 会帮你找到依赖。

    ```
    import ctypes

    lib = ctypes.CDLL('libm.so.6')
    func = getattr(lib, 'pow')
    func.argtypes = [ctypes.c_double, ctypes.c_double]
    func.restype = ctypes.c_double

    print (func(2, 10))
    ```
    Shazoo
        6
    Shazoo  
       2018-05-28 18:51:45 +08:00
    我觉得有点像比较初级的库路径问题。可能是你的 LD_LIBRARY 设置有些问题。
    一般做这种工作的步骤大概是:
    1、先写个 C 的程序,简单调用下 SDK 功能。如果 C 程序链接、运行有问题,那就及时解决。
    2、C 程序搞定后,再弄成 python 库。

    一般来说,库都会依赖不少第三方和系统库。这部分依赖,一般做的好的 SDK 是无需关心的。只要能搜索到就可以。做的不好的 SDK,也应该可以在步骤 1 解决掉。

    参考下?
    http://oi.0w0.io/2018/01/05/Ubuntu-16-04-Python3-%E9%85%8D%E7%BD%AESQLite3-%E7%9A%84-icu-%E5%88%86%E8%AF%8D/#more
    wsds
        7
    wsds  
    OP
       2018-05-28 19:22:41 +08:00
    @qieqie 首先就是用的 ctypes 的,调用 so 报错:undefined symbol: _ZN6apache6thrift12GlobalOutputE
    然后才换的 cffi
    wsds
        8
    wsds  
    OP
       2018-05-28 19:23:06 +08:00
    @Shazoo 看报错像是路径有问题,但我代码跟 so 就在同级目录下啊,不该是路径问题啊
    wsds
        9
    wsds  
    OP
       2018-05-28 19:24:08 +08:00
    @qieqie 函数名,入参,出参,都有文档,可现在首要是调不通 so
    wevsty
        10
    wevsty  
       2018-05-28 19:34:26 +08:00
    @wsds
    undefined symbol: _ZN6apache6thrift12GlobalOutputE
    表示的是找不到_ZN6apache6thrift12GlobalOutputE 这个函数,这个函数可能是哪个 so 中引用了,但是你系统里面没有。
    google 一下这个函数大概是来自这些 so 文件
    /usr/lib64/libthriftnb.so.0.0.0
    /usr/lib/libthriftz-1.0.0-dev.so
    所以你得看你系统是否安装了 libthrift ?或者版本是否正确?
    gnaggnoyil
        11
    gnaggnoyil  
       2018-05-28 19:37:53 +08:00
    _ZN6apache6thrift12GlobalOutputE 不出意外应该是来自 Apache Thrift 的库的 symbol.LZ 你 Apache Thrift 装了没?

    @wsds 人家说的是你那个库的依赖库没配置好,你为什么要强调你的"代码怎么着怎么着"......
    lonccc
        12
    lonccc  
       2018-05-28 19:38:57 +08:00 via Android
    pybind11 了解一下
    wsds
        13
    wsds  
    OP
       2018-05-28 19:49:37 +08:00
    @wevsty lib 下有这个库 libthrift.so
    wsds
        14
    wsds  
    OP
       2018-05-28 19:50:08 +08:00
    @wevsty 不过,目录有什么要求吗?我是从别的地方拷过来的
    wevsty
        15
    wevsty  
       2018-05-28 20:11:30 +08:00
    @wsds
    Linux 默认不会搜索工作目录这样,如果 so 不是在 /usr/lib 或者 /lib 这样的地方,那么就需要你指定路径。
    可以修改 /etc/ld.so.conf 这样来加载,但是既然缺少库,用包管理安装一下不是更好么?
    wsds
        16
    wsds  
    OP
       2018-05-28 20:14:44 +08:00
    @wevsty 我试过绝对路径,也是还是提示:undefined symbol: _ZN6apache6thrift12GlobalOutputE

    ```
    from cffi import FFI

    ffi = FFI()

    # ffi.cdef()
    lib_IOTCAPIs = ffi.dlopen("/home/install/linux/x86_64/lib/libthrift.so")
    lib_IOTCAPIs = ffi.dlopen("/home/lib/cpu/libIFaceRecSDK.so")
    print('Loaded lib {0}'.format(lib))
    ```
    wevsty
        17
    wevsty  
       2018-05-28 22:01:32 +08:00
    @wsds 那只能说明这个函数可能不在这个 so 文件里,再去检查这个库有没有其他的 so 文件吧。
    qieqie
        18
    qieqie  
       2018-05-29 00:12:04 +08:00
    @wsds export LD_LIBRARY_PATH=/home/install/linux/x86_64/lib:$LD_LIBRARY_PATH
    Shazoo
        19
    Shazoo  
       2018-05-29 09:40:11 +08:00
    @wsds 都说啦~写个简单 c 程序。调试通了,再跑 python。这样就能排除库本身问题。善用 readelf 之类的工具,导出引用表看看。

    当然,如果已经通了,那就实验下 LD_LIBRARY
    wsds
        20
    wsds  
    OP
       2018-05-29 10:55:04 +08:00
    @Shazoo 加载通了,但调里边 C 的方法,提示 AttributeError: function
    AX5N
        21
    AX5N  
       2018-05-29 11:00:48 +08:00
    @wsds
    你以前尝试过调用 c 的库没,如果没有的话,建议你写个 hello world 试试。
    我大概猜到你啥问题了,不过还是建议你先自己试试。
    wsds
        22
    wsds  
    OP
       2018-05-29 11:10:21 +08:00
    @AX5N 以前用 python 调用过 C,调通了的
    wsds
        23
    wsds  
    OP
       2018-05-29 11:10:34 +08:00
    @AX5N 求告之,快被开除了
    AX5N
        24
    AX5N  
       2018-05-29 13:14:36 +08:00
    @wsds 不好意思 可能是我理解错了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1255 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 17:20 PVG 01:20 LAX 09:20 JFK 12:20
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86