与语言混全编程之复数数组的参数传递方法

核心提示引言前段时间在作信号分析处理方面的项目时,需要将时域数据通过快速傅立叶变换转换到频域以便作进一步的后续处理,由于涉及到实时运算速度方面的要求,需要考虑程序算法的运算性能问题,因此,信号处理算法是在C语言里面完成的,然后将算法的实现函数封装到

介绍

前段时间在做信号分析与处理项目的时候,需要通过快速傅立叶变换将时域数据转换到频域,以便进一步的后续处理。由于实时运算速度的要求,我需要考虑程序算法的性能。因此,用C语言完成了信号处理算法,然后将算法的实现功能封装成一个动态链接库文件。最后我用Python调用了DLL文件中的函数,通过GUI界面程序图形化的显示了运算结果。这就涉及到如何将C语言中复杂的数组类型与Python中的数据类型进行交互。

在Python语言中,可以使用ctypes模块调用其他用C++语言编写的DLL文件中的函数。在前面的文章中,已经提到了传递数字/指针/字符串参数、传递结构参数和传递通用数组类型的例子。可以回顾一下,这样可以更好的理解你这次要讲的内容。

此示例的运行环境配置如下:

①操作系统:64位win7

② Python版本:python2.7.14

③功能约定的通话模式:C通话模式。

具体实现过程如下。

功能描述

DLL文件中设计了一个函数ComplexArrayFunc。它的作用是将输入长度为n的复数组X中每个复元素的实部和虚部进行交换,得到相同长度的复数组Y。该函数的声明如下图所示:

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

下面是Python中转换为numpy数组的调用方法。

Python中的调用方法

如前几篇文章所述,可以考虑直接使用ctypes模块将上述函数中的复杂数组X声明为复杂类型的指针,即以“point”的形式。但是在ctypes模块中声明指针类型时,模块中没有c_complex类型的指针,所以这个方法不容易实现。

一般来说,C语言和Python语言用DLL文件编程时,DLL函数中的数组类型可以转换成numpy库中的数组类型。这样做的好处是可以借助numpy强大的分析处理功能直接处理数据。

在numpy库中,直接支持复杂数组类型的声明。

根据这个想法,Python中的函数声明和调用如下:

上述方法中,在声明函数的参数类型时,对于参数x和y类型复杂的指针变量,使用np.ctypeslib.ndpointer直接将numpy中的数组声明为C语言中的复杂数组类型。最后,numpy中的数组类型A和B被传递给函数。

需要注意的是,复数类型的指针X和Y的类型要声明为np.complex128,因为在C语言中,指针X和Y的实部和虚部都是double类型的数据,所以numpy中对应的复数类型是8*2=16Bytes=128bits。

在Python中使用这种调用方法的好处是,只需要在文件中声明一次函数原型。虽然声明起来比较麻烦,但是在Python中可以在很多地方多次调用该函数,不需要额外的转换工作就可以直接使用numpy中的数组类型。

完整的测试代码

完整的测试代码如下图所示:

操作结果如下图所示:

从运行结果可以看出,包含三个复数元素的数组A的实部和虚部已经互换,复数数组B已经正确输出。这种调用方法可以实现C语言复数组和numpy复数组之间正确的数据传递。

摘要

从这个例子可以看出,在Python中,通过ctypes模块调用用C++语言编写的其他DLL文件中的函数,不仅可以提高软件的运行效率,还可以充分利用目前市面上各种第三方DLL库函数,从而扩展Python软件的功能和应用领域,减少重复编写代码和构建轮子的工作量,充分体现了Python作为一种胶水语言的独特优势。

本文由编码那些事原创,请关注+转发+收藏+点赞,带你一起学习!

 
友情链接
鄂ICP备19019357号-22