设为首页 收藏本站
查看: 1104|回复: 0

[经验分享] PY++ 自动将你的C++程序接口封装供python调用

[复制链接]

尚未签到

发表于 2015-4-21 07:55:35 | 显示全部楼层 |阅读模式

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")
        .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
#include
#include
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 m_friend;
};
void haha();
#endifchg.cc#include "chg.h"
void haha()
{
cout  > 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接口,是不是都是这么搞出来的呢,我估计是。。。 呵呵

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-59002-1-1.html 上篇帖子: 我看Python代码缩进 下篇帖子: 利用python自动清除Android工程中的多余资源
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表