使用Python向C语言的链接库传递数组、结构体、指针类型的数据


Posted in Python onJanuary 29, 2019

使用python向C语言的链接库传递数组、结构体、指针类型的数据

由于最近的项目频繁使用python调用同事的C语言代码,在调用过程中踩了很多坑,一点一点写出来供大家参考,我们仍然是使用ctypes来调用C语言的代码库。

至于如何调用基础数据类型的数据,请大家参考我的另外一篇文章:Python使用ctypes调用C/C++的方法

1. 使用python给C语言函数传递数组类型的参数

想必很多时候,C语言会使用数组作为参数,在之前我们使用过ctypes的一些数据类型作为C语言参数类型,包括byte、short、int、double之类的,但是在使用数组类型的时候,我们也是有着类似的做法,下面我们看实例:

1.1 C语言的代码块

一个简单的数组输入,以及一个简单将数组作为参数的函数

int input[2] = [0, 1]
void printIntArray(int[] input){
  for(int i = 0; i < 2; i ++){
    print(input[i]);
  }
}

1.2 python代码块

下面我们将演示如何调用上面的代码

from ctypes import *
# 假设上面的代码被编译成了一个XXXXlib.so的文件
dll = CDLL('XXXXlib.so')
# 声明一个数组类型
INPUT = c_int * 2
# 实例化一个长度为2的整型数组
input = INPUT()
# 为数组赋值(input这个数组是不支持迭代的)
input[0] = 1
input[1] = 2
# 引用C语言的函数
print_int_array = dll.printIntArray
# 调用C语言的函数
print_int_array(input)

1.3 小结

使用数组的方法基本就是这样的,声明什么类型的数组只需要根据之前python官方文档里ctypes使用说明对照着声明数组就可以了。

2. 使用python给C语言函数传递结构体类型的参数

当然,为了满足一些个性化的需求和为了使程序更容易让人理解,更多的时候开发人员也会使用结构体类型的变量为函数赋值。现在我们使用ctypes来实例化一个C语言的结构体,请看实例:

由于第一部分我们已经介绍了如何简单的调用C语言的函数,我们下面只写结构体相关的python代码

from ctypes import *
# 声明一个类,继承自ctypes.Structure
class PythonStructure(Structure):
  _fields_:[('param1',c_int),('param2', c_int),('param3', c_int * 2)]
# 实例化变量
python_structure = PythonStructure()
# 赋值
python_structure.param1 = 1
python_structure.param2 = 3
PARAM = c_int * 2
param3 = PARAM()
param3[0] = 3
param3[1] = 4
python_structure.param3 = param3

从代码中我们可以看到,我们声明了一个class,使其继承自ctypes.Structure,然后在类的内部声明了变量,fields这样一个变量域,里面用元组存贮这结构体的每个结构体内部变量的变量名和数据类型。

然后在实际的使用过程中,首先要实例化一个PythonStructure类型的变量,然后为其各个内部变量赋值。

3. 使用python给C语言函数传递指针类型的参数

指针作为C语言相比于其他原因最大的优势,在C语言程序中会大量的使用指针,因此将指针类型的数据作为参数传递其实是十分的普遍的,下面我们直接上实例:

3.1 C语言函数声明

void test(pystruct *ps)

假设这里的pystruct与我们在第二部分声明的结构体相对应(我这渣渣C语言功底实在是怕写出什么错误的代码误导大家)

3.2 python代码

使用指针类型的数据只需要在调用btref()就可以了

from ctypes import *
# 声明一个类,继承自ctypes.Structure
class PythonStructure(Structure):
  _fields_:[('param1',c_int),('param2', c_int),('param3', c_int * 2)]
# 实例化变量
python_structure = PythonStructure()
# 赋值
python_structure.param1 = 1
python_structure.param2 = 3
PARAM = c_int * 2
param3 = PARAM()
param3[0] = 3
param3[1] = 4
python_structure.param3 = param3
# 开始调用
dll = CDLL('XXXXlib.so')
test = dll.test
# 传递参数
test(byref(python_structure))

4.写在最后

以上就是我们今天踩过的坑,其实发现网上对于ctypes的相关文章不是很多,因此想写出来跟大家分享一下,希望大家少踩坑,快速的完成任务,远离加班,周末愉快!

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。如果你想了解更多相关内容请查看下面相关链接

Python 相关文章推荐
详解详解Python中writelines()方法的使用
May 25 Python
深入讲解Python中的迭代器和生成器
Oct 26 Python
Python使用dis模块把Python反编译为字节码的用法详解
Jun 14 Python
Python进阶篇之字典操作总结
Nov 16 Python
python将list转为matrix的方法
Dec 12 Python
python 字典套字典或列表的示例
Dec 16 Python
Tensorflow安装问题: Could not find a version that satisfies the requirement tensorflow
Apr 20 Python
django的autoreload机制实现
Jun 03 Python
django序列化时使用外键的真实值操作
Jul 15 Python
Matplotlib中%matplotlib inline如何使用
Jul 28 Python
如何用Python 实现全连接神经网络(Multi-layer Perceptron)
Oct 15 Python
如何用tempfile库创建python进程中的临时文件
Jan 28 Python
pandas去重复行并分类汇总的实现方法
Jan 29 #Python
spark dataframe 将一列展开,把该列所有值都变成新列的方法
Jan 29 #Python
Python使用ctypes调用C/C++的方法
Jan 29 #Python
dataframe 按条件替换某一列中的值方法
Jan 29 #Python
Numpy之random函数使用学习
Jan 29 #Python
pandas DataFrame 删除重复的行的实现方法
Jan 29 #Python
使用Python向DataFrame中指定位置添加一列或多列的方法
Jan 29 #Python
You might like
将PHP作为Shell脚本语言使用
2006/10/09 PHP
PHP strip_tags() 去字符串中的 HTML、XML 以及 PHP 标签的函数
2016/05/22 PHP
yii2中dropDownList实现二级和三级联动写法
2017/04/26 PHP
JavaScript与函数式编程解释
2007/04/27 Javascript
一个可以随意添加多个序列的tag函数
2009/07/21 Javascript
面向对象的Javascript之二(接口实现介绍)
2012/01/27 Javascript
jQuery获取注册信息并提示实现代码
2013/04/21 Javascript
js实现键盘操作实现div的移动或改变的原理及代码
2014/06/23 Javascript
浅谈Javascript中匀速运动的停止条件
2014/12/19 Javascript
cookie的secure属性详解
2015/04/08 Javascript
JQUERY的AJAX请求缓存里的数据问题处理
2016/02/23 Javascript
微信小程序 监听手势滑动切换页面实例详解
2017/06/15 Javascript
总结JavaScript在IE9之前版本中内存泄露问题
2018/04/28 Javascript
vue中动态设置meta标签和title标签的方法
2018/07/11 Javascript
vue-cli 构建骨架屏的方法示例
2018/11/08 Javascript
页面内锚点定位及跳转方法总结(推荐)
2019/04/24 Javascript
layui 实现table翻页滚动条位置保持不变的例子
2019/09/05 Javascript
[02:04]2016国际邀请赛中国区预选赛VG.R晋级之路
2016/07/01 DOTA
[01:00:59]VP VS VG Supermajor小组赛胜者组第二轮 BO3第二场 6.2
2018/06/03 DOTA
Python(Tornado)模拟登录小米抢手机
2013/11/12 Python
Python实现针对含中文字符串的截取功能示例
2017/09/22 Python
Python基于多线程实现ping扫描功能示例
2018/07/23 Python
django drf框架中的user验证以及JWT拓展的介绍
2019/08/12 Python
Python综合应用名片管理系统案例详解
2020/01/03 Python
打印tensorflow恢复模型中所有变量与操作节点方式
2020/05/26 Python
iphoneX 适配客户端H5页面的方法教程
2017/12/08 HTML / CSS
英国Radley包德国官网:Radley London德国
2019/11/18 全球购物
亚洲航空公司官方网站:AirAsia
2019/11/25 全球购物
Java中的类包括什么内容?设计时要注意哪些方面
2012/05/23 面试题
连带责任保证书
2014/04/29 职场文书
小学节能减排倡议书
2014/05/15 职场文书
实习单位指导教师评语
2014/12/30 职场文书
教代会闭幕词
2015/01/28 职场文书
大学生团员个人总结
2015/02/14 职场文书
开票证明
2015/06/23 职场文书
MySQL中日期型单行函数代码详解
2021/06/21 MySQL