利用swig实现python调用C/C++的方法

Python是一门语法简单而且清晰的脚本语言,不过执行效率比较低。简单的说就是开发相对C/C++容易,但是执行效率不如C/C++,甚至有人称之为执行效率最低的鱼眼。如果可以将最重要的而且变化一般不大的运算逻辑用 C/C++实现,其他用python书写,那就最好不过了。据说python底层就是用C实现的,因此这一想法也是可行的。目前来说,python调用C/C++有以下几种方法:

1)  利用python提供的API调用C。主要方法是在c++文件中借助Python提供的头文件python.h,对C/Cpp函数进行封装。然后将它编译为一个动态链接库(一个Module)。最后在Python文件中将这个module 加载进去,就可以调用了。具体例子请见http://blog.csdn.net/marising/article/details/2845339

2)  利用boost工具进行封装。相对1)来说更为方便,但是和1)一样都需要对原C代码进行破坏。具体例子请见http://blog.csdn.net/marising/article/details/2917827

3)  利用ctypes。ctypes是Python标准库提供的调用动态链接库的模块,相对1)2)来说不需要对源代码进行破坏,只需要对相应的c++数据类型进行python的转换。但是据说对C/C++的支持不一定完整.

4)  利用Swig工具。Swig和boost一样是一个对C进行封装的工具,但是和boost不一样,它不需要对源代码进行破坏,只需要新增一个接口文件对需要封装的函数和类进行描述,swig会自动对c代码封装成一个能被调用的module供Python调用。

        下面具体介绍一下Swig的使用方法。刚才说了,swig和boost不一样,它不用对源代码进行破坏,只需要在外面多写一个接口文件。假设有如下的cpp文件需要封装:

<span style="margin: 0px; padding: 0px; border: 0px; font-size: 14px; background-color: transparent; background-position: initial initial; background-repeat: initial initial;">#include <time.h>
 double My_variable = 3.0;
 
 int fact(int n) {
     if (n <= 1) return 1;
     else return n*fact(n-1);
 }
 
 int my_mod(int x, int y) {
     return (x%y);
 }
 	
 char *get_time()
 {
     time_t ltime;
     time(<ime);
     return ctime(<ime);
 }</span>


       那么我们需要写如下接口文件(example.i):

<span style="margin: 0px; padding: 0px; border: 0px; font-size: 14px; background-color: transparent; background-position: initial initial; background-repeat: initial initial;"> %module example
 %{
 /* Put header files here or function declarations like below */
#define SWIG_FILE_WITH_INIT
 extern double My_variable;
 extern int fact(int n);
 extern int my_mod(int x, int y);
 extern char *get_time();
 %}
 
 extern double My_variable;
 extern int fact(int n);
 extern int my_mod(int x, int y);
 extern char *get_time();</span>


      这是Python tutorial中的一个例子。下面将具体介绍一下example.i这个文件。

      %module 后面的名字是被封装的模块名称。封装口,python通过这个名称加载程序

     %{  %}之间所添加的内容,一般包含此文件需要的一些函数声明和头文件。

      最后一部分,声明了要封装的函数和变量。

      比较建议的写法是,把要封装的函数声明部分写成头文件,假如为example.h,这样接口文件就非常简单了:

<span style="margin: 0px; padding: 0px; border: 0px; font-size: 14px; background-color: transparent; background-position: initial initial; background-repeat: initial initial;"> %module example
 %{
 /* Put header files here or function declarations like below */
#define SWIG_FILE_WITH_INIT
#include"example.h"
 %}
 
%include"example.h"</span>


     为了编译出一个封装的动态库,依次执行

<span style="margin: 0px; padding: 0px; border: 0px; font-size: 14px; background-color: transparent; background-position: initial initial; background-repeat: initial initial;"> $ swig -python -c++ example.i
 $ g++ -c -fPIC example_wrap.cxx -I/usr/local/include/python2.6
 $ g++ -shared example_wrap.o -o _example.so</span>


       第一步的过程会生成example_wrap.cxx的文件。因为现在是cpp文件,所以编译出来是个.cxx文件和一个example_wrap.py。如果是c的文件,编译后会出现一个.c的文件。这个文件相当于将原cpp文件进行了封装,wrap了一层。后面两步就是标准的生成动态链接库的步骤了。这样得到的动态链接库就可以直接被python import了。

<span style="margin: 0px; padding: 0px; border: 0px; font-size: 14px; background-color: transparent; background-position: initial initial; background-repeat: initial initial;"> >>> import example
 >>> example.fact(5)
 120
 >>> example.my_mod(7,3)
 1
 >>> example.get_time()
 'Tue Dec 11 23:01:07 2012'
 >>></span>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值