资讯专栏INFORMATION COLUMN

Python的C/C++扩展——用SWIG封装C++为Python模块

邹强 / 668人阅读

摘要:所以,最大的好处就是将脚本语言的开发效率和的运行效率有机的结合起来。前面的文章提到一个实现的双数组的实现,它在中文分词新词发现等算法中的应用。本文以的封装实现来说明的使用。编译生成动态库编译生成的使用的,可以参考的编写。

如果觉得文章对你有帮助,你也可以访问老猿的个人博客https://www.yuanrenxue.com/

Python调用C/C++代码的利器除了boost_python外,还有SWIG(Simplified Wrapper and Interface Generator),它是用来为脚本语言调用C和C++程序的软件开发工具,它实际上是一个编译器,获取C/C++的声明和定义,用一个壳封装起来,以便其它脚本语言访问这些声明。所以,SWIG 最大的好处就是将脚本语言的开发效率和 C/C++ 的运行效率有机的结合起来。

前面的文章提到一个C++实现的双数组Trie Tree的实现:cedar,它在中文分词、新词发现等算法中的应用。本文以cedar的SWIG封装实现来说明SWIG的使用。

0. 安装swig

工欲善其事必先利其器,首先要安装swig,Ubuntu安装swig很简单:

sudo aptitude install swig

1. 声明和定义C/C++代码

在cedar的swig目录下面有cedar的C++声明和实现代码trie.h,但是这个实现里面没有遍历所有key的函数方法,所以我添加了一个实现,首先定义一个数据结构来定义key:

// key-value pair return type for next_key()
class kv_t {
    public:
        std::string key;
        int value;
};

添加一个函数每次返回一个key,当key字符串为空时表示遍历结束,继续调用的话就又从头开始遍历:

  // to iterate all keys
  kv_t next_key() const {
    static size_t from = 0, p = 0;
    union { int i; int x; } b;
    char key[256] = {0};
    kv_t kv;
    if(from == 0) {
        b.i = _t->begin(from, p);
    }else{
        b.i = _t->next(from, p);
    }
   if (b.i == trie_t::CEDAR_NO_PATH) {
        kv.key = "";
        kv.value = 0;
        from = 0;
        p = 0;
        return kv;
    }
    _t->suffix(key, p, from);
    kv.key = key;
    kv.value = b.x;
    return kv;
  }

2. 编写接口文件.i

查看cedar.i可以看到SWIG的接口文件的编写规则:

首先在 %module 后面声明模块名称,这就是Python在import时使用的模块名称;
在%{ … %}之间包含相关头文件
在%include 后面可以声明对STL的支持
最后声明要封装的函数和变量,也可以之间包含头文件: %include “trie.h”

3. 封装代码

可以在Makefile里面看到python-bindings:

python-bindings: 
        swig -Wall -python -builtin -outdir python -c++ cedar.i
        mv -f cedar_wrap.cxx python

直接make或者多带带运行上面的swig命令,就可以生成cedar.py和cedar_wrap.cxx文件。

4. 编译生成动态库

编译生成的cedar_wrap.cxx使用python distutils的setup,可以参考python/setup.py的编写。setup.py的build如下:

python setup.py build

就会在当前目录下面创建目录build,下面生成lib.linux-x86_64-2.7/cedar.py 和 _cedar.so

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/43421.html

相关文章

  • SWIGC++ 库进行 Python 包装

    摘要:可以在接口文件中直接引用库里的内容,大大方便接口文件的编写。使用库里的这里先介绍方式通过创建出来的数组是数组的直接代理,非常底层和高效,但是,它也和数组一样不安全,一样没有边界检查。对由于这种情况,可以使用库里的。 如果你也像我们一样,同时使用Python和C++,以获得两种语言的优势,一定也会希望寻找一种好的方式集成这两种语言,相比而言,让Python能够方便使用C++的库更加重要,...

    jas0n 评论0 收藏0
  • PythonC/C++方式

    摘要:调用方式方式一基础篇这种方法叫做的扩展使用这样调用引用的头文件包裹函数,用来包裹需要转化为的函数,在方法前面加下划线。定义名称通常和文件名保持一致。执行命令在下,使用编译器生成对应的文件。 Python调用C++方式 方式一(基础篇) 这种方法叫做python的扩展 int great_function(int a) { return a + 1; } 使用python这样调用...

    PiscesYE 评论0 收藏0
  • Tensorflow代码解析(二)

    摘要:为了进一步了解的逻辑,图对和进行了展开分析。另外,在命名空间中还隐式声明了控制依赖操作,这在章节控制流中相关说明。简述是高效易用的开源库,有效支持线性代数,矩阵和矢量运算,数值分析及其相关的算法。返回其中一块给用户,并将该内存块标识为占用。 3. TF 代码分析初步3.1 TF总体概述为了对TF有整体描述,本章节将选取TF白皮书[1]中的示例展开说明,如图 3 1所示是一个简单线性模型的TF...

    zhigoo 评论0 收藏0
  • 深度学习:你该知道八大开源框架

    摘要:作为当下最热门的话题,等巨头都围绕深度学习重点投资了一系列新兴项目,他们也一直在支持一些开源深度学习框架。八来自一个日本的深度学习创业公司,今年月发布的一个框架。 深度学习(Deep Learning)是机器学习中一种基于对数据进行表征学习的方法,深度学习的好处是用 非 监督式或半监督式 的特征学习、分层特征提取高效算法来替代手工获取特征(feature)。作为当下最热门的话题,Google...

    Rindia 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<