您的位置:首页 > 编程语言 > C语言/C++

高效开发Python扩展模块方法:用SWIG封装C/C++代码

2014-11-24 16:29 781 查看
最近想在python上开发应用程序,但以前写了一些c++的代码想用上,所以搜了搜,方法不少,但没有一个符合自己

现在根据网络上的文档,重新写了一份

开发环境是WINDOWS,python2.7 swig3.0.2

开发方法其实有两种:

一是遵从python扩展模块API规范,用C/C++直接写python模块;

此方法开发出来的扩展模块(DLL动态库),可看做原生的python模块,

不需要依赖其他第三方库;缺点是,开发需要写大量的规范的C/C++到Python的转换代码

(这部分代码按照规范写就可以,算是体力劳动);

一是使用SWIG工具,这样,开发高性能的C/C++代码后,不用再手工写从C/C++到python的转换代码,

这个工作SWIG帮你做了。可谓十分方便,所谓高手,也就是能熟练使用各种工具及原理,

并运用的实际设计中。呵呵,下面就这种方法,做一个简单介绍:

使用SWIG包裹C/C++代码生成python扩展模块步骤

1写SWIG的接口文件(.i),见下面例子:

<span style="margin: 0px; padding: 0px; border: 0px; font-size: 14px; background-image: initial; background-attachment: initial; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: 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>


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

<span style="margin: 0px; padding: 0px; border: 0px; font-size: 14px; background: transparent;"> %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>


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

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

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

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

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

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

%include"example.h"</span>


4 第一步的过程会生成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: transparent;"> >>> import example
>>> example.fact(5)
120
>>> example.my_mod(7,3)
1
>>> example.get_time()
'Tue Dec 11 23:01:07 2012'
>>></span>


5 使用SWIG自动生成包裹类(即C/C++到python的转换代码)

E:\code\swigwin-2.0.9>swig.exe -c++ -python E:\2013\01\2013-01-16\CalcMesh\TMC\TMC.i

6 python扩展模块编译安装

准备setup.py脚本如下:

from distutils.core import setup, Extension

ext_module = Extension(‘_tmc’,

include_dirs = [r'..\..\..\..\..\code\gdal\ogr\ogrsf_frmts\shape'],

define_macros = [('TMC_EXPORTS', '1')],

libraries = ['LibPort', 'LibShape'],

library_dirs = [r'..\Test\Release'],

sources = ['TMC_wrap.cxx', 'PreProcessTMC.cpp'],

)

setup(name=’tmc’,

version=’1.0.0′,

description = ‘This is a demo package’,

ext_modules = [ext_module],

py_modules = ['tmc'],

)

注意Extension里面的模块name为_tmc(需要加下划线前缀,否则会出现链接错误)

7 python setup.py build

enjoy it.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: