python调用动态链接库的基本过程详解


Posted in Python onJune 19, 2019

动态链接库在Windows中为.dll文件,在linux中为.so文件。以linux平台为例说明python调用.so文件的使用方法。
本例中默认读者已经掌握动态链接库的生成方法,如果不太清楚的可以参考动态链接库的使用

调用上例动态链接库的使用中的sum.so

import ctypes
so = ctypes.CDLL('./sum.so')

print "so.sum(50) = %d" % so.sum(50)
so.display("hello world!")
print "so.add() = %d" % so.add(ctypes.c_float(2), ctypes.c_float(2010))

output

so.sum(50) = 1275
hello world!
so.add() = 2012

注意:

  • 如果python在调用C函数内部出现了问题,系统不会提示具体出现什么问题,只会提示"segmentation fault"。所以最好是先用C语言调用该动态库验证没有问题了再提供给python调用。
  • python传参给C函数时,可能会因为python传入实参与C函数形参类型不一致会出现问题( 一般int, string不会有问题,float要注意 )。这时需要在python调用时传入的实参做一个类型转换(见so.add(float, float)函数的调用)。转换方式见下表:

python调用动态链接库的基本过程详解

数组的传入传出

如果将python中list传入C函数数组,则需要提前转换。

import ctypes
pyarray = [1, 2, 3, 4, 5]
carrary = (ctypes.c_int * len(pyarray))(*pyarray) //有点类似malloc的方式生成carray
print so.sum_array(carray, len(pyarray))

refer

如果如果需要将C array返回python,需要提前把array传入,然后在C函数中修改,返回时再把c array转换为np.array

pyarray = [1,2,3,4,5,6,7,8]
carray = (ctypes.c_int*len(pyarray))(*pyarray)
so.modify_array(carray, len(pyarray))
print np.array(carray)

output

[10 20 30 40 50 60 70 80]

也可以用形参方式提前定义函数接口,然后再传入numpy结构

import ctypes
import numpy as np
from numpy.ctypeslib import ndpointer
so = ctypes.CDLL('./sum.so')
pyarray = np.array([1,2,3,4,5,6,7,8], dtype="int32")
fun = so.modify_array
fun.argtypes = [ndpointer(ctypes.c_int), ctypes.c_int]
fun.restype = None
fun(pyarray, len(pyarray))
print np.array(pyarray)

注意:numpy中的数据类型指定很重要,即dtype的设定

图片的传入传出

转递数据域

背景知识:

python中的opencv图片是用numpy的方式保存的,而opencv3 C语言的图片数据结构为cvMat (IplImage已经逐弃用)
所以需要把python中numpy图片转换为ctypes.POINTER(ctypes.c_ubyte)的指针转入其数据域,再将其行列信息传入,就可以在C中从最底层初始化一个CvMat,如果要初始化一个别数据结构的图片也是同理(如darknet的image,caffe的blob)
python numpy image 转换为 C pointer的方法

python_frm.ctypes.data_as(C.POINTER(ctypes.c_ubyte))

注意:传入numpy image前一定要确保numpy image是numpy array数据类型

比如我遇到的bug

image = cv2.imread("xxx.jpg");

image传入ctypes_so.fun之中图片是有效的,但

image = cv2.imread("xxx.jpg");

这时候进入ctypes_so.fun的图片会变成一个乱码

即,crop之后的numpy image的type虽然也为numpy array,但实际传入的image data却不正确

解决方法:

无论是何种方式得到的numpy image,都强行转换为numpy array,再传入ctypes_so.fun

image = numpy.array(image)

可以解决这个bug

refence

如果使用opencv2 可以考虑直接将numpy image转换为IplImage

opencv3 python已经不支持cv2.cv的函数了

但Opencv2可能还可以尝试以下方法

numpy image to iplimage

python调用C++中的类

因为python不能直接调用C++中的类,所以必须把C++中的类转换为C的接口

转换原则

  • 所有的C++关键字及其特有的使用方式均不能出现在.h文件里,.h中仅有C函数的包装函数声明
  • 在class.cpp中实现对类的成员函数接口转换的函数,包括对类内成员的读写函数get() and set()
  • 如果要在包装函数中要实例化对象,尽量用new constructor()的将对象的内存实例化在堆中,否则对象会被析构
  • 记得在所有包含函数声明的文件中加入以下关键字,声明该函数为C函数,否则该函数的符号不会记录在二进制文件中
#ifdef __cplusplus
extern "C" {
#endif
xxxxxx function declaration xxxxx
#ifdef __cplusplus
}
#endif

code
refer
refer

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现随机密码字典生成器示例
Apr 09 Python
深入理解NumPy简明教程---数组3(组合)
Dec 17 Python
Linux RedHat下安装Python2.7开发环境
May 20 Python
python方向键控制上下左右代码
Jan 20 Python
Python实现购物车购物小程序
Apr 18 Python
python爬取个性签名的方法
Jun 17 Python
利用Pycharm断点调试Python程序的方法
Nov 29 Python
解决python 未发现数据源名称并且未指定默认驱动程序的问题
Dec 07 Python
pyqt远程批量执行Linux命令程序的方法
Feb 14 Python
python使用pip安装模块出现ReadTimeoutError: HTTPSConnectionPool的解决方法
Oct 04 Python
Python爬虫实现vip电影下载的示例代码
Apr 20 Python
python中如何进行连乘计算
May 28 Python
python中使用ctypes调用so传参设置遇到的问题及解决方法
Jun 19 #Python
华为校园招聘上机笔试题 扑克牌大小(python)
Apr 22 #Python
PyQt5实现从主窗口打开子窗口的方法
Jun 19 #Python
python操作kafka实践的示例代码
Jun 19 #Python
利用pyuic5将ui文件转换为py文件的方法
Jun 19 #Python
PyQt5实现让QScrollArea支持鼠标拖动的操作方法
Jun 19 #Python
pyqt 实现为长内容添加滑轮 scrollArea
Jun 19 #Python
You might like
微信网页授权(OAuth2.0) PHP 源码简单实现
2016/08/29 PHP
扩展jQuery 键盘事件的几个基本方法
2009/10/30 Javascript
关于jQuery新的事件绑定机制on()的使用技巧
2013/04/26 Javascript
JavaScript实现网页上的浮动广告的简单方法
2013/06/14 Javascript
使用js对select动态添加和删除OPTION示例代码
2013/08/12 Javascript
5个数组Array方法: indexOf、filter、forEach、map、reduce使用实例
2015/01/29 Javascript
javascript实时显示北京时间的方法
2015/03/12 Javascript
jQuery+css3实现文字跟随鼠标的上下抖动
2015/07/31 Javascript
深入理解JavaScript中的并行处理
2016/09/22 Javascript
微信小程序 教程之条件渲染
2016/10/18 Javascript
js倒计时显示实例
2016/12/11 Javascript
Jquery实时监听input value的实例
2017/01/26 Javascript
vue中使用vue-router切换页面时滚动条自动滚动到顶部的方法
2017/11/28 Javascript
小程序ios音频播放没声音问题的解决
2018/07/11 Javascript
vue19 组建 Vue.extend component、组件模版、动态组件 的实例代码
2019/04/04 Javascript
uni-app微信小程序登录并使用vuex存储登录状态的思路详解
2019/11/04 Javascript
webpack proxy 使用(代理的使用)
2020/01/10 Javascript
antd-DatePicker组件获取时间值,及相关设置方式
2020/10/27 Javascript
vue+iview实现文件上传
2020/11/17 Vue.js
13个最常用的Python深度学习库介绍
2017/10/28 Python
python3实现磁盘空间监控
2018/06/21 Python
对PyQt5中树结构的实现方法详解
2019/06/17 Python
Django项目中实现使用qq第三方登录功能
2019/08/13 Python
Python Django 添加首页尾页上一页下一页代码实例
2019/08/21 Python
Django实现WebSSH操作物理机或虚拟机的方法
2019/11/06 Python
python实现删除列表中某个元素的3种方法
2020/01/15 Python
python matplotlib画盒图、子图解决坐标轴标签重叠的问题
2020/01/19 Python
Python如何脚本过滤文件中的注释
2020/05/27 Python
python使用matplotlib的savefig保存时图片保存不完整的问题
2021/01/08 Python
matplotlib交互式数据光标实现(mplcursors)
2021/01/13 Python
巧用HTML5给按钮背景设计不同的动画简单实例
2016/08/09 HTML / CSS
美国办公用品购物网站:Quill.com
2016/09/01 全球购物
MATCHESFASHION.COM法国官网:英国奢侈品零售商
2018/01/04 全球购物
专科应届生求职信
2013/11/24 职场文书
公司授权委托书样本
2014/09/15 职场文书
Python使用sql语句对mysql数据库多条件模糊查询的思路详解
2021/04/12 Python