Python如何调用DLL函数:C数组与numpy数组传递

引言

在Python语言中,可以使用ctypes模块调用其它如C++语言编写的动态链接库DLL文件中的函数,在提高软件运行效率的同时,也可以充分利用目前市面上各种第三方的DLL库函数,以扩充Python软件的功能及应用领域,减少重复编写代码、重复造轮子的工作量,这也充分体现了Python语言作为一种胶水语言所特有的优势。

前面两篇已经讲了传递数值/指针/字符串参数、传递结构体参数的例子,大家可以回看一下,这样可以更好的理解本次要讲的内容。详细细节请参考:Python如何调用DLL函数:传递数值、指针与字符串参数、Python使用ctypes模块调用DLL函数传递结构体参数

这次讲一下在Python中使用ctypes模块调用DLL中的库函数传递数组参数的情况。一般情况下,DLL函数中传递C语言类型的数组,在接收到Python语言中时,通常将其转换为numpy库里面的数组类型,这样做的好处是可以借助于numpy强大的分析处理功能对数据直接作后续处理。这次通过例子演示下C语言数组到numpy数组之间是怎样传递的。

同样,操作系统环境是win7 64位,Python使用的版本是python2.7.14,函数约定的调用方式为C调用(cdecl)方式。

例子说明

在DLL文件中设计一个函数GenSine,其功能是根据给定的参数(包括数据点数N、信号频率f、采样频率Fs、信号幅值A、初始相位initPhase、偏移offset等参数)产生一个正弦波形数据,返回时间向量数组x(横坐标数据)和波形数据y(纵坐标数据)。该函数的声明如下图所示:

函数GenSine的具体C语言实现代码如下:

下面给出两种Python中转为numpy数组的调用方法。

Python中调用方法1

在Python中的调用方式如下:

上面的代码中在声明函数的参数类型时,对于前两个参数x和y数组变量,将其声明为指向double类型的指针即可。在调用该函数时,先声明两个numpy库中的数组t1、y1,数据类型为float64,将其作为参数传递到该函数中时,使用的是numpy中的ctypes.data_as(POINT(c_double))转化为C语言中的指向double类型的指针类型,这样就可以实现numpy中数组与C语言数组中的完美转换。

Python中调用方法2

在Python中的调用方式如下:

与第1种方法不同的是,这种方法在声明函数的参数类型时,对于前两个参数x和y数组变量,使用np.ctypeslib.ndpointer(dtype=np.float64,ndim=1,flags="C_CONTIGUOUS")直接将numpy中的数组声明为C语言中的数组类型,最后调用时,直接将将numpy中的数组类型t2和y2传到该函数中即可。相比于第1种方法,虽然在声明时麻烦些,但在调用时可以直接使用numpy中的数组类型,相对来说要简洁些,毕竟函数声明只需声明一次即可,但调用函数可能会在程序中出现多次。

完整的测试代码

在测试程序中,使用了pyqtgraph库画两种方法产生的正弦波形图,不明白的可以翻看下前面的文章,专门介绍了该库的画图方法。完整的测试代码如下图所示:

运行结果如下图所示:

从运行结果可以看出,两种调用方法,都可以实现C语言数组与numpy数组之间数据正确的传递。相比来说,第2种方法更简洁些。

欢迎加关注,共同交流。

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20181027A0153900?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券