使用Python向C语言的链接库传递数组、结构体、指针类型的数据
使用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的相关文章不是很多,因此想写出来跟大家分享一下,希望大家少踩坑,快速的完成任务,远离加班,周末愉快!
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接
相关文章
详解pandas使用drop_duplicates去除DataFrame重复项参数
这篇文章主要介绍了详解pandas使用drop_duplicates去除DataFrame重复项参数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-08-08Python2.7版os.path.isdir中文路径返回false的解决方法
这篇文章主要为大家详细介绍了Python2.7版os.path.isdir中文路径返回false的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2019-06-06cv2.imread 和 cv2.imdecode 用法及区别
对于路径中含有中文的图像,直接用cv2.imread读取会报错,上次看到有大佬使用cv2.imdecode就可以正常读取,有点好奇,所以今天来记录下二者用法和区别,感兴趣的朋友跟随小编一起看看吧2023-02-02Python爬虫请求模块Urllib及Requests库安装使用教程
requests和urllib都是Python中常用的HTTP请求库,使用时需要根据实际情况选择,如果要求使用简单、功能完善、性能高的HTTP请求库,可以选择requests,如果需要兼容性更好、功能更加灵活的HTTP请求库,可以选择urllib2023-11-11Python实现基本Socket服务端与客户端通信的完整代码
这篇文章主要介绍了Python实现基本Socket服务端与客户端通信,分步详解与完整代码都有,按需所求即可,对Python Socket服务端与客户端通信相关知识感兴趣的朋友一起看看吧2023-06-06Python如何将给定字符串中的大写英文字母按以下对应规则替换
这篇文章主要介绍了Python如何将给定字符串中的大写英文字母按以下对应规则替换,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-10-10
最新评论