PY++ 自动将你的C++程序接口封装供python调用
2015-12-16 11:16
1031 查看
引言:
我喜欢C++的速度,我喜欢python的简洁,我相信只用C++,python就可以解决99.99%的问题,那么如何让它们交互呢,这里仅说明如何将C++的代码接口封装使得python可以调用c++。一个简单的应用我写了一个分词器,我希望能通过网页形式展示给别人,我觉得用django做这这件事情比用C++些XML更灵活方便。那么如何让python代码能够调用我的分词器呢?我在前面的文章介绍过boost.python使得C++中方便调用python,boost.python入门教程----python嵌入c++
其实boost.pthon也可以用于封装C++,使得python方便的调用C++代码。我也写过用swig实现C++封装
简单对比boost.python和swig:
我推荐使用boost.python。boost.python对于python的扩展和嵌入即双向都支持,对于python调用C++的需求,两者都需要手工鞋代码封装需要的C++接口,但是boost.python更强大灵活更方便些。为什么用py++:
我很懒,我不喜欢手工去封装,那是很机械的事情,作为一个很弱的算法工程师我也不希望花时间去写这些机械代码。。。如果项目很大怎么办,很多接口,都要手工去写。。。mygod,我干脆不想用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++的安装:
安装gccxmlpy++首先依赖gccxml的分析功能解析C++代码结构,这个很强大。。。,安装如下
wget
$mkdirgccxml-build
$cdgccxml-build
$cmake..-DCMAKE_INSTALL_PREFIX:PATH=/installation/path
$make
$makeinstall
如果这个个编译不行,用CVS最新的版本
cvs-d:pserver:anoncvs@www.gccxml.org:/cvsroot/GCC_XMLcogccxml
安装pygccxml
svnco
然后进入各个子目录发现有setup.py的
执行pythonsetup.pyinstall
PY++使用示例:
好了我们用一个最简单的代码进行示例,更细节的功能有待进一步学习:假设我们有chg.hchg.cc两个文件,我们要将其接口封装为python可调用的接口。
chg.h
#ifndefchg_ #definechg_ #include<iostream> #include<vector> #include<string> usingnamespacestd; classChg { public: Chg(): m_age(28){m_friend.push_back("mm");} intgetAge() { returnm_age; } intfriendSize() { returnm_friend.size(); } intm_age; vector<string>m_friend; }; voidhaha(); #endif
chg.cc
#include"chg.h" voidhaha() { cout<<"hahaha"<<endl; }
我们需要写一个python脚本帮助自动完成封装,如果你不想做进一步的细致设置比如哪些接口被封装,哪些不被封装,你可以像下面这么写,甚至写个脚本帮助自动生成下面的代码。当然你要细致设置可以去参考下py++的入门教程也很简单。
importos importsys frompyplusplusimportmodule_builder mb=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被生成了出来,它的样子如下
//ThisfilehasbeengeneratedbyPy++.
#include"boost/python.hpp"
#include"boost/python/suite/indexing/vector_indexing_suite.hpp"
#include"chg.h"
namespacebp=boost::python;
BOOST_PYTHON_MODULE(libchg_py){
{//::std::vector<std::string>
typedefbp::class_<std::vector<std::string>>vector_less__std_scope_string__greater__exposer_t;
vector_less__std_scope_string__greater__exposer_tvector_less__std_scope_string__greater__exposer=vector_less__std_scope_string__greater__exposer_t("vector_less__std_scope_string__greater_");
bp::scopevector_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
typedefvoid(*haha_function_type)();
bp::def(
"haha"
,haha_function_type(&::haha));
}
}
是的如你所见py++的功能就是自动生成boost.python代码。。。而没有py++你需要手工完成这些事情,py++真的很lifesaving。
好了通过编译chg.ccchg_py.cc注意你要链接boost.python和python动态链接库。我的CmakeList里面是这么写的
add_library(chg_pySHAREDchg_py.ccchg.cc)
target_link_libraries(chg_pylibboost_python.solibpython2.6.so)
看下效果吧(注意我用的cmake会自动生成libchg_py.so):
In[1]:fromlibchg_pyimport*
In[2]:chg=Chg()
In[3]:chg.getAge()
Out[3]:28
In[4]:printlen(chg.m_friend)
1
In[5]:chg.m_friend[0]
Out[5]:'mm'
In[6]:haha()
hahaha
C++有很多庞大的库比如计算几何相关的CGAL库,它们大都有python接口,是不是都是这么搞出来的呢,我估计是。。。呵呵
相关文章推荐
- c++: allocator, uninitialized_copy, uninitialized_fill_n
- 23种设计模式C++实例之组合模式
- 23种设计模式C++实例之桥接模式
- 开发中遇到C++ 问题,记在这里,方便以后查看
- 23种设计模式C++实例之装饰模式
- 23种设计模式C++实例之代理模式
- c语言基础
- oc中new和init的区别
- 23种设计模式C++实例之适配器模式
- Blade - 腾讯开源的构建系统 c/c++编译环境
- c++11: allocator construct
- windows C++ 创建快捷方式API, 100% 能运行
- 在vs2008 C++下调试控制台程序的心得及技巧
- Pro*C/C++具体操作
- 23种设计模式C++实例之外观模式
- C语言中define的用法
- OC语言——把四个十进制三位数存放到一个数组中,然后按升序排序
- c++ 自定义排序容器set
- C++命名空间namespace
- C++ 类模板不能实现分离式编译