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的使用方法。它不用对源代码进行破坏,只需要在外面多写一个接口文件。
如下Cpp code:
#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); }需要写如下接口文件(example.i)
%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();
这是Python tutorial中的一个例子
%module 后面的名字是被封装的模块名称, 封装口,python通过这个名称加载程序。
%{ %}之间所添加的内容,一般包含此文件需要的一些函数声明和头文件。
最后一部分,声明了要封装的函数和变量。
比较建议的写法是,把要封装的函数声明部分写成头文件,假如为example.h,这样接口文件就非常简单了:
%module example %{ /* Put header files here or function declarations like below */ #include"example.h" %} %include"example.h"
下面是编译的过程,
注意: 1. 在Windows环境中使用,编译成DLL文件或pyd文件,Linux中使用编译成so文件。
2. 如果你有VC studio 环境,可能容易些,但是可能有些问题。可以用free的MinGW的编译环境。在编译命令中一定要指定c/c++库的路径,还有python库的路径。
执行以下编译命令:
swig -c++ -python example.i g++ -c example.cpp -I C:\MinGW\include -I .\ g++ -c example_wrap.cxx -I c:\python27\include -I c:\MinGW\include -I C:\Python27\Lib\site-packages\numpy\core\include\ g++ -shared -I C:\Python27\include -I C:\Python27\Lib\site-packages\numpy\core\include\ example.o example_wrap.o -o _example.pyd -L C:/Python27/libs/ -lpython27
如果还报错,可以试试多加 "- I" 指定你的include 路径。
第一步的过程会生成example_wrap.cxx的文件。因为现在是cpp文件,所以编译出来是个.cxx文件和一个example_wrap.py。如果是c的文件,编译后会出现一个.c的文件。这个文件相当于将原cpp文件进行了封装,wrap了一层。后面两步就是标准的生成动态链接库的步骤了。
这样得到的动态链接库就可以直接被python import了, 注意copy example.py and example.pyd 到你的使用目录。
>>> import example
>>> example.fact(5) 120 >>> example.my_mod(7,3) 1 >>> example.get_time() 'Tue Dec 11 23:01:07 2012'
-------Good Luck !