python中使用ctypes调用so传参设置

栏目: Python · 发布时间: 5年前

内容简介:近日在做一组声纹聚类时,使用了另一团队同学开发的声纹距离算法。该算法对外提供的是一组so包,需要使用方自己去使用。在python中调用纯so包一般使用ctypes类库,用起来看起来简单但也有不少细节容易犯错。本次使用过程中,就遇到传参的问题。目标so库中对外export的函数是大致如下的三个函数:这三个函数使用起来倒也简单,顺序使用就可以了。但发现写成如下形式的python代码后,执行会直接segment fault。

问题

近日在做一组声纹聚类时,使用了另一团队同学开发的声纹距离算法。该算法对外提供的是一组so包,需要使用方自己去使用。在 python 中调用纯so包一般使用ctypes类库,用起来看起来简单但也有不少细节容易犯错。本次使用过程中,就遇到传参的问题。

目标so库中对外export的函数是大致如下的三个函数:

void* create_handler();
    int extract_feature(void* hander);
    bool destroy(void* handler);

这三个函数使用起来倒也简单,顺序使用就可以了。但发现写成如下形式的python代码后,执行会直接segment fault。

import sys
    import ctypes
    
    so = ctypes.CDLL("./lib/libbase.so")
    p = so.create_handler()
    feature = so.extract_feature(p)
    so.destroy(p)

解决

这段代码中p是int类型,由void*自动转来,在ctyeps中这种转型本身是没问题的。segment fault发生在extract_feature函数调用中,问题应当出在参数上,回传的handler已经不是原来的pointer了,导致访问指针出错。

查阅ctypes的文档后,发现ctypes可以声明so库中函数的参数,返回类型。试了试,显示声明后问题得到了解决,证明我们的猜想是对的,确实指针发生了变化。修改后代码如下:

import sys
    import ctypes
    
    so = ctypes.CDLL("./lib/libbase.so")
    so.create_handler.restype=ctypes.c_void_p
    so.extract_feature.argtypes=[ctypes.c_void_p]
    so.destroy.argtypes=[ctypes.c_void_p]
    
    p = so.create_handler()
    feature = so.extract_feature(p)
    so.destroy(p)

结论:

ctypes中传递指针类型参数需要显示声明c函数的参数,返回类型。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

网站入侵与脚本攻防修炼

网站入侵与脚本攻防修炼

逍遥 / 2008-9 / 59.00元

《网站入侵与脚本攻防修炼》从“攻”、“防”两个角度,通过现实中的入侵实例,并结合原理性的分析,图文并茂地展现网站入侵与防御的全过程。全书共分8章,系统地介绍网站入侵的全部过程,以及相应的防御措施和方法。其中包括网站入侵的常见手法、流行网站脚本入侵手法揭密与防范、远程攻击入侵网站与防范、网站源代码安全分析与测试等。《网站入侵与脚本攻防修炼》尤其对网站脚本漏洞原理进行细致的分析,帮助网站管理员、安全人......一起来看看 《网站入侵与脚本攻防修炼》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具