python 实践之 ctypes

来源:互联网 发布:mac改变桌面图标大小 编辑:程序博客网 时间:2024/05/02 01:22
近段时间工作中,需要对一个算法的有效性做批量验证,这种活我一般都是用python + pySide搞定。验证通过之后,再转换为C代码。之前一直是这么做的,因为python调整算法很快。但这次的算法比较复杂,用python实现起来固然方便(list操作太方便了),却还要经过一道转换,需要做单元测试。为了充分发挥懒人精神,决定算法部分直接用C代码实现,python负责界面和数据加载及预处理(处理为产品上的数据格式)。花了点时间研究了一下ctypes,以下就是笔记,我重点应用的是数组/指针类型的参数。
#include <stdio.h>__declspec( dllexport ) int func_test(unsigned short anInputSignal1[], int nLen1, unsigned short anInputSignal2[], int nLen2, unsigned short *pnOutput, int *pLen);int func_test(unsigned short anInputSignal1[], int nLen1, unsigned short anInputSignal2[], int nLen2, unsigned short *pnOutput, int *pLen){int i = 0;for (i = 0; i < nLen1; i++){printf("%d, ", anInputSignal1[i]);}printf("\n");for (i = 0; i < nLen2; i++){printf("%d, ", anInputSignal2[i]);}printf("\n");for (i = 0; i < *pLen; i++)pnOutput[i] = i;*pLen = 1;return 0;}
编译成为 dll,放到python工程文件夹下,test.py内容如下:

import ctypesimport arrayinputSignal1 = array.array('H')inputSignal1.fromlist(range(1, 10))inputSignal2 = array.array('H')inputSignal2.fromlist(range(11, 20))cInputArrayType = (ctypes.c_ushort * len(inputSignal1))cInputSignal1 = cInputArrayType(*inputSignal1)cInputSignal2 = cInputArrayType(*inputSignal2)cOutputArray = (ctypes.c_ushort * 10)()cOutLen = ctypes.c_int(10)mydll = ctypes.CDLL('ctypes.test.dll')mydll.func_test(cInputSignal1,                 ctypes.c_int(len(inputSignal1)),                 cInputSignal2,                 ctypes.c_int(len(inputSignal2)),                 cOutputArray,                ctypes.byref(cOutLen))print cOutLen.valuefor data in cOutputArray:    print data

其中比较tricky的一点就是用于C类型的数组入参初始化,先利用python的array模块将list转换为array,然后用array初始化C类型的数组。

输出如下:

1, 2, 3, 4, 5, 6, 7, 8, 9,
11, 12, 13, 14, 15, 16, 17, 18, 19,
1
0
1
2
3
4
5
6
7
8
9

剩下的数据类型可以参考文档,写的挺好的,就是初始化部分开始让我有些纠结,呵呵。

原创粉丝点击