设为首页 加入收藏

TOP

Python与C/C++混合编程的应用(二)
2018-11-20 22:10:00 】 浏览:476
Tags:Python C/C 混合 编程 应用
://docs.python.org/2.7/extending/extending.html


使用SWIG,来生成独立的wrap文件


这种方式并不能算是一种新方式,实际上是基于第二中方式的一种包装。SWIG是个帮助使用C或者C++编写的软件能与其它各种高级编程语言进行嵌入联接的开发工具。SWIG能应用于各种不同类型的语言包括常用脚本编译语言例如Perl, PHP, Python, Tcl, Ruby, PHP,C#,Java,R等。


操作上,是针对c/c++程序编写独立的接口声明文件(通常很简单),swig会分析c/c++源程序自动分析接口要如何包装。在指定目标语言后,swig会生成额外的包装源码文件。编译so库时,把包装文件一起编译、连接即可。看个c代码例子:


int system(const char* command)
{
        sts = system(command);
        if (sts < 0) {
                return NULL;
        }
        return sts;
}


c源码中去掉适配python的包装,仅定义system函数本身,这比第二种方式简洁很多,并且剔除了c代码与python的耦合代码,是c代码通用性更好。
然后编写swig接口声明文件spam.i:


%module spam
%{
#include "spam.h"
%}
%include "spam.h"
%include "typemaps.i"
int system(const char* INPUT);


这是一段语言无关的模块声明,要创建一个叫spam的模块,对system做一个声明,主要是声明参数作为入参使用。然后执行swig编译程序:


>swig -c++ -python spam.i


swig会生成spam_wrap.cxx和spam.py两个文件。先看spam_wrap.cxx,这个生成的文件很长,但关键的就是对函数的包装:



包装函数传入的还是PyObejct对象,内部进行了类型转换,最终调了源码中的system函数。
生成的了另一个spam.py实际上是对so库又用python包装了一层(实际比较多余):



这里使用_spam模块,这里实际上是把扩展命名为了_spam。关于swig在python上的应用可以参见:http://www.swig.org/Doc1.3/Python.html
下面就是编译和安装python 模块,Python提供了distutils module,可以很方便的编译安装python的module。像下面这样写一个安装脚本setup.py:



执行 python setup.py build,即可以完成编译,程序会创建一个build目录,下面有编译好的so库。so库放在当前目录下,其实Python就可以通过import来加载模块了。当然也可以用 python setup.py install 把模块安装到语言的扩展库——site-packages目录中。关于build python扩展,可以参考https://docs.python.org/2/extending/building.html#building


混合编程性能分析


混合编程的使用场景中,很重要一个就是性能攸关。那么这小节将通过几个小实验验证下混合编程的性能如何,或者说怎样写程序能发挥好混合编程的性能优势。


我们使用冒泡排序算法来验证性能。


1)实验一 使用冒泡程序验证python和c/c++程序的性能差距


python版冒泡程序:


def bubble(arr,length):
    j = length - 1
    while j >= 0:
        i = 0
        while i < j:
            if arr[i] > arr[i+1]:
                tmp = arr[i+1]
                arr[i+1] = arr[i]
                arr[i] = tmp
            i += 1
        j -= 1


c语言版冒泡排序


void bubble(int* arr,int length){
    int j = length - 1;
    int i;
    int tmp;
    while(j >= 0){
        i = 0;
        while(i < j){
            if(arr[i] > arr[i+1]){
                tmp = arr[i+1];
                arr[i+1] = arr[i];
                arr[i] = tmp;
            }
            i += 1;
        }
        j -= 1;
    }
}


使用一个长度为100内容固定的数组,反复排序10000次(每次排序后,再把数组恢复成原始序列),记录执行时间:
在相同的机器上多次执行,Python版执行时间是10.3s左右,而c语言版本(未使用任何优化编译参数)执行时间只有0.29s左右。相比之下python的性能的确差很多(主要是python中list的操作跟c的数组相比,效率差非常多),但python中很多扩展都是c语言写的,目的就是为了提升效率,python用于数据分析的numpy库就拥有不错的性能。下个实验就验证,如果python使用c语言版本的冒泡排序扩展库,性能会提升多少。


2)实验二 python语言使用ctypes方式调用
这里直接使用c_int来定义了数组对象,这也节省了调用时数据类型转换的开销:


import time
from ctypes import *
IntArray100 = c_int * 100
arr = IntArray100(87

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C语言求最大公约数代码及解析 下一篇C语言实现农夫过河代码及解析

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目