PY++ 自动将你的C++程序接口封装供python调用
来源:互联网 发布:商之友软件 编辑:程序博客网 时间:2024/06/05 09:47
http://www.cnblogs.com/rocketfan/archive/2010/11/30/1892429.html
PY++ 自动将你的C++程序接口封装供python调用
written by pku_goldenlock at qq.com
引言:
我喜欢C++的速度,我喜欢python的简洁,我相信只用C++,python就可以解决99.99%的问题,那么如何让它们交互呢,这里仅说明如何将C++的代码接口封装使得python可以调用c++。一个简单的应用我写了一个分词器,我希望能通过网页形式展示给别人,我觉得用django做这这件事情比用C++些XML更灵活方便。那么如何让python代码能够调用我的分词器呢?我在前面的文章介绍过boost.python使得C++中方便调用python,boost.python入门教程 ----python 嵌入c++
python嵌入C++------ boost.python如何在C++中调用含有不定长参数tuple变量和关键字参数dict变量的函数, 这是所谓的python嵌入C++,
其实boost.pthon也可以用于封装C++,使得python方便的调用C++代码。我也写过用swig实现C++封装二叉树显示(图形界面,控制台字符),简单表达式求值,pyqt,swig初试....。
简单对比boost.python和swig:
我推荐使用boost.python。boost.python对于python的扩展和嵌入即双向都支持,对于python调用C++的需求,两者都需要手工鞋代码封装需要的C++接口,但是boost.python更强大灵活更方便些。
为什么用py++:
我很懒,我不喜欢手工去封装,那是很机械的事情,作为一个很弱的算法工程师我也不希望花时间去写这些机械代码。。。如果项目很大怎么办,很多接口,都要手工去写。。。my god,我干脆不想用python调它了。。。
例如
class_<AdRanker > ("AdRanker")
.def("load", &AdRanker::load)
.def("getAds", &AdRanker::getAds)
.def("loadFile", &AdRanker::loadFile)
.def("getAdRankInfoVec", &AdRanker::getAdRankInfoVec, return_internal_reference<>())
.def("getAdRankInfo", &AdRanker::getAdRankInfo, return_internal_reference<>())
.def("getSegString", &AdRanker::getSegString)
.def("getSegStringVec", &AdRanker::getSegStringVec)
.def("getPhraseOrgExtend", &AdRanker::getPhraseOrgExtend)
.def("getPhraseFinalExtend", &AdRanker::getPhraseFinalExtend)
.def("getPhraseExtendCat", &AdRanker::getPhraseExtendCat)
;
我希望这一切可以自动化!而PY++可以省去你手工封装的过程帮助你生成类似上面的代码!即py++可以帮你自动生成使用boost.python手工写的封装代码。
以下都是讲linux环境下的安装和使用。
PY++的安装:
- 安装gccxml
py++首先依赖gccxml的分析功能解析C++代码结构,这个很强大。。。,安装如下
wget http://www.gccxml.org/files/v0.6/gccxml-0.6.0.tar.gz
$ mkdir gccxml-build
$ cd gccxml-build
$ cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/installation/path
$ make
$ make install
如果这个个编译不行 ,用CVS最新的版本
cvs -d :pserver:anoncvs@www.gccxml.org:/cvsroot/GCC_XML co gccxml
- 安装pygccxml
svn co https://pygccxml.svn.sourceforge.net/svnroot/pygccxml pygccxml
然后进入各个子目录发现有setup.py 的
执行python setup.py install
PY++使用示例:
好了我们用一个最简单的代码进行示例,更细节的功能有待进一步学习:
假设我们有chg.h chg.cc两个文件,我们要将其接口封装为python可调用的接口。
chg.h
#ifndef chg_#define chg_#include <iostream>#include <vector>#include <string>using namespace std;class Chg{ public: Chg(): m_age(28){ m_friend.push_back("mm");} int getAge() { return m_age; } int friendSize() { return m_friend.size(); } int m_age; vector<string> m_friend;};void haha();#endif
chg.cc
#include "chg.h"void haha(){ cout << "hahaha" << endl;}
我们需要写一个python脚本帮助自动完成封装,如果你不想做进一步的细致设置比如哪些接口被封装,哪些不被封装,你可以像下面这么写,甚至写个脚本帮助自动生成下面的代码。当然你要细致设置可以去参考下py++的入门教程也很简单。http://www.language-binding.net/pyplusplus/pyplusplus.html#
import osimport sysfrom pyplusplus import module_buildermb = module_builder.module_builder_t( files=['chg.h'] #要需要封装的头文件 ,gccxml_path='/usr/local/bin/gccxml')mb.build_code_creator( module_name='libchg_py' ) #要生成的python模块的名称mb.code_creator.user_defined_directories.append( os.path.abspath('.') )mb.write_module( os.path.join( os.path.abspath('.'), 'chg_py.cc' ) ) #要生成的boost.python封装好的代码文件的名称
好了执行上面的文件我们就可以看到chg_py.cc被生成了出来,它的样子如下
// This file has been generated by Py++.#include "boost/python.hpp"#include "boost/python/suite/indexing/vector_indexing_suite.hpp"#include "chg.h"namespace bp = boost::python;BOOST_PYTHON_MODULE(libchg_py){ { //::std::vector< std::string > typedef bp::class_< std::vector< std::string > > vector_less__std_scope_string__greater__exposer_t; vector_less__std_scope_string__greater__exposer_t vector_less__std_scope_string__greater__exposer = vector_less__std_scope_string__greater__exposer_t( "vector_less__std_scope_string__greater_" ); bp::scope vector_less__std_scope_string__greater__scope( vector_less__std_scope_string__greater__exposer ); vector_less__std_scope_string__greater__exposer.def( bp::vector_indexing_suite< ::std::vector< std::string >, true >() ); } bp::class_< Chg >( "Chg", bp::init< >() ) .def( "friendSize" , (int ( ::Chg::* )( ) )( &::Chg::friendSize ) ) .def( "getAge" , (int ( ::Chg::* )( ) )( &::Chg::getAge ) ) .def_readwrite( "m_age", &Chg::m_age ) .def_readwrite( "m_friend", &Chg::m_friend ); { //::haha typedef void ( *haha_function_type )( ); bp::def( "haha" , haha_function_type( &::haha ) ); }}
是的如你所见py++的功能就是自动生成boost.python代码。。。而没有py++你需要手工完成这些事情,py++真的很life saving。
好了 通过编译chg.cc chg_py.cc 注意你要链接boost.python和python动态链接库。我的CmakeList里面是这么写的
add_library(chg_py SHARED chg_py.cc chg.cc)
target_link_libraries(chg_py libboost_python.so libpython2.6.so)
看下效果吧(注意我用的cmake会自动生成libchg_py.so):
In [1]: from libchg_py import *
In [2]: chg = Chg()
In [3]: chg.getAge()
Out[3]: 28
In [4]: print len(chg.m_friend)
1
In [5]: chg.m_friend[0]
Out[5]: 'mm'
In [6]: haha()
hahaha
C++有很多庞大的库比如计算几何相关的CGAL库,它们大都有python接口,是不是都是这么搞出来的呢,我估计是。。。 呵呵
- PY++ 自动将你的C++程序接口封装供python调用
- PY++ 自动将你的C++程序接口封装供python调用
- PY++ 自动将你的C++程序接口封装供python调用
- 用boost封装C++的库供Python调用
- python 接口实现 供第三方调用
- python中调用另一个文件下的.py程序
- 将所获取的行集合 转换为Map封装为类 供调用
- 利用boost.python封装C++函数供python调用
- 将c++静态库实现二次封装供java调用
- c++调用python封装接口
- python调用c接口
- 将python或R生成的模型存为PMML供java调用
- 【Python】 两行命令将.py 的Python脚本 转换成.exe 程序
- Python调用采用Boost Python封装的c++(2)
- Python调用采用Boost Python封装的c++(2)
- 在lua5.2.3的环境下,vs2012生成c的dll程序块供lua调用
- 将C++接口封装成C函数
- 忙里偷闲-封装汇编编写的水波特效供C++调用
- java-reflect
- cocos2dx番外篇——更换精灵图片
- 新手,让我们记忆慢慢记录吧!
- 项目笔记:6.利用LVS实现网站流量高效快速的分发
- c++中的构造函数和析构函数
- PY++ 自动将你的C++程序接口封装供python调用
- 23种设计模式(3):抽象工厂模式
- Hadoop2.6集群环境虚拟机中搭建网络配置
- java学习之旅28--_面向对象_01_面向过程和面向对象的本质区别
- GCC --sysroot=dir switch meaning
- 宝马M4前挡风玻璃贴保护膜_宝马玻璃贴膜_玻璃盾甲
- Java 正则表达式语法规则、字典、索引
- MongDB入门简介
- 23种设计模式(4):建造者模式