avatar GDYSHI

gdyshi 的个人博客

  • 首页
  • 子域
  • 分类
  • 标签
  • 归档
  • 关于
首页 python调用第三方动态库
文章

python调用第三方动态库

发表于 2018/08/10
作者 gdyshi
5 分钟阅读
python调用第三方动态库
python调用第三方动态库
  • 摘要
  • 引言
  • 主题
    • 加载动态库
    • 类型
    • 函数
  • 实例
  • 附录
  • 参考

摘要

本文讲述python混合编程之调用动态库

引言

python因为良好的编码性和扩展库正被大规模的使用,但他有两个缺点:1、代码可见;2、执行效率低,于是在实际应用中经常会把高效和核心代码用C/C++实现,业务部分用python实现。这就需要进行混合编程,本文对python调用动态库的方法及注意事项进行记录

主题

python标准库函数中提供了调用动态库的包————ctypes

加载动态库

  • 查找动态库ctypes.util.find_library
  • 根据动态库调用方式的不同,可以分为cdecl和stdcall两种,这两种方式的主要区别见下表。后面的例子以cdecl调用方式为例,stdcall类同。

    调用标准内存栈维护者函数名
    cdecl调用者前面加下划线,后面加“@”符号和参数的字节数
    stdcall被调用者在输出函数名前面加下划线
  • ctypes加载动态库有两种方式。构造类对象libc = CDLL("libtestlib.dll")和实例化instancelibc = cdll.LoadLibrary("libtestlib.dll")。这两种方式都会返回一个动态库操作的句柄,以供后面使用

类型

  • 常规参数类型

C常规参数类型与ctypes、python类型对应关系表如下:

C typectypes typePython type
_Boolc_boolbool (1)
charc_char1-character bytes object
wchar_tc_wchar1-character string
charc_byteint
unsigned charc_ubyteint
shortc_shortint
unsigned shortc_ushortint
intc_intint
unsigned intc_uintint
longc_longint
unsigned longc_ulongint
__int64 or long longc_longlongint
unsigned __int64 or unsigned long longc_ulonglongint
size_tc_size_tint
ssize_t or Py_ssize_tc_ssize_tint
floatc_floatfloat
doublec_doublefloat
long doublec_longdoublefloat
char * (NUL terminated)c_char_pbytes object or None
wchar_t * (NUL terminated)c_wchar_pstring or None
void *c_void_pint or None
  • 指针
    • 弱引用指针byref(),这种方式速度更快
    • 强指针pointer()
    • c_types定义的指针c_char_p、c_wchar_p、c_void_p不可修改,如果需要在C函数中被修改,需要使用函数create_string_buffer()创建可变内存
    • 用指针的value属性获取指针指向的内容
  • 结构体/联合体
    • 通过构建类继承Structure/Union来实现结构体的定义,把结构体属性组合成元组数组放在类中的_fields属性中。关于结构体的其它特性(对齐、指针嵌套、位域等)请参照官网
      1
      2
      3
      4
      5
      6
      
      class POINT(Structure):
         _fields_ = [("x", c_int),
                     ("y", c_int)]
      class RECT(Structure):
         _fields_ = [("upperleft", POINT),
                     ("lowerright", POINT)]
      
  • 数组直接使用类型 * 元素个数的方式来定义,如array = c_int * 10

  • 函数指针(回调函数)CFUNCTYPE
    • 使用注释的方式一次定义
      1
      2
      3
      4
      
      @CFUNCTYPE(c_int, c_int)
      def py_cb_func(a):
          print("py_cb_func", str(a))
          return a + 1
      
    • 标准方式
      1
      2
      3
      4
      5
      6
      
      # 定义c_types类型
      PY_CB_FUNC = CFUNCTYPE(c_int, c_int)
      def py_cb_func(a):
          print("py_cb_func", str(a))
          return a + 1
      cb_func = PY_CB_FUNC(py_cmp_func)
      

函数

  • 函数入参声明libtest.parm_int.argtypes = [c_int],做了函数声明后,会在python调用时对参数格式进行检查
  • 函数返回值类型声明libtest.parm_int.restype = c_int,做了函数声明后,会在python调用时对参数格式进行检查
  • 函数调用ret = libtest.parm_int(c_int(1))

实例

我专门针对c_types调用动态库写了一个实例。实例包括两个部分

  • 用C实现的动态库代码。主要从入参类型、返回值类型、回调函数调用三个方面实现及提供接口
  • 用python实现的对动态库调用代码。用于调用动态库的所有接口

附录

参考


  • python标准库
  • ctypes官方文档
python
python 混合编程 动态库 C
本文由作者按照 CC BY 4.0 进行授权
分享

最近更新

  • paho.mqtt.embedded掉线问题记录
  • tensorflow模型部署系列————TensorFlow Serving部署
  • tensorflow模型部署系列————独立简单服务器部署
  • tensorflow模型部署系列————浏览器前端部署
  • tensorflow模型部署系列————独立简单服务器部署
外部链接
  • 996.icu
  •  此博客的 Github 仓库
  •  GDYSHI 的个人博客

文章内容

相关文章

2018/03/22

WFDB库解析

摘要 引言 主题 代码结构 wfdb.io _header _signal annotation 主要方法 download ...

2018/06/27

logging模块多进程解决方案

摘要 引言 主题 logging模块 flask 问题场景 问题原因 解决方案 总结 附录 参考 摘要 本文讲述如何在多进程中使用logging模块记录到同一文件 引言 从Python2.3起,Python的标准库加入了logging模块。 logging模块是Python内置的标准...

2018/11/27

tensorflow模型导出记录

摘要 引言 主题 meta方式 查找最终输出的op 查找输入tensor 验证能否强行使用feed_dict改变变量的值 batchnorm问题 附录 参考 摘要 本文记录部署一个非标准模型(未定义name、未定义placeholder、未定义batchnorm中的train参数)的过程 引言 之前训练的一个比较好的模...

logging模块多进程解决方案

译文 FaceNet: A Unified Embedding for Face Recognition and Clustering

© 2025 gdyshi. 保留部分权利。

本站采用 Jekyll 主题 Chirpy

热门标签

tensorflow keras 模型部署 神经网络 机器学习 flask python 服务器 译文 人脸识别

发现新版本的内容。