boost.python入门教程 ----python 嵌入c++

13 篇文章 0 订阅

http://www.cnblogs.com/rocketfan/archive/2009/11/15/1603400.html

boost.python 中 python 嵌入c++ 部分,网上找到的中文资料似乎都有些过时了,

如 boost.python学习笔记 http://edyfox.codecarver.org/html/boost_python.html

boost.python版本2中,提供更加简洁易用的接口,我们可以使用从而

代替原始的PyRun_SimpleString等等python c 转换api.

 

关于python与C++混合编程,事实上有两个部分 

  1. extending   所谓python 程序中调用c/c++代码, 其实是先处理c++代码, 预先生成的动态链接库, 如example.so,  而在python代码中import example;即可使用c/c++的函数 .
  2. embedding  c++代码中调用 python 代码.

两者都可以用 python c 转换api,解决,具体可以去python官方文档查阅,但是都比较繁琐. 

对于1,extending,常用的方案是boost.python以及swig.

swig是一种胶水语言,粘合C++,PYTHON,我前面的图形显示二叉树的文章中提到的就是利用pyqt作界面,

调用c++代码使用swig生成的.so动态库.

而boost.python则直接转换,可以利用py++自动生成需要的wrapper.关于这方面的内容的入门除了boost.python

官网,中文的入门资料推荐

 

用Boost.Python + CMake + wxPython构建跨语言GUI程序<一> 

 

http://www.cppblog.com/skyscribe/archive/2009/08/09/92686.html

一共3个系列吧,他的博客上还有cmake的内容,本文的环境也将使用cmake编译,可供参考. 

对于2 似乎swig就不提供支持了,swig 不仅仅支持 python调用c/c++,还支持许多其它高级语言调用c++, 但是它不支持python 嵌入c++. 


下面仅仅介绍2 embedding, 事实上embedding 比 extending 简单的多:)

本将会给出具体实例代码以及环境配置方法.有些只是为了简单,并不是最好的配置方案,

如cmake的使用. 

  • 环境配置  

   我的工作环境是ubuntu8.04,gcc4.24,cmake2.6,boost1.4,python2.6.

       如果你在windows下工作就不用往下看了. 

       boost.python似乎还不支持python3 所以个人推荐使用python2.6,当然ubuntu8.04自带的python2.5

        也可以的. 

      1.python2.6 的安装 

             去官网下载python2.6,解压缩,

             ./configure --enable-shared;make; sudo make install

             头文件应该会默认安装到/usr/local/include/python2.6.

             注意第一步 ./configure --help可以查看帮助选项,如你想设置安装到什么路径,

             特别注意 --enable-shared选项生成动态链接库,libpython2.6.so 

             这个是我们下面需要的一定要有这个选项! 默认会生成到/usr/local/lib下,你直接./configure 

             的话则不会生成动态链接库.

          2. cmake  安装

              sudo apt-get insall cmake即可,也可以去官网下载安装最新的cmake2.8

          3. boost   安装

             去官网下载boost.1.4.2 解压缩

             ./bootstrap.sh  --help

             ./bootstrap.sh --show-libraries  #会显示你有哪些库可以安装

             这里解释一下,因为boost是模板库,很多都只需要头文件,不需要编译安装,但是有些库是需要安装的如

             regex,python, 等等,你可以查看一下选择自己需要安装的库.

              我选择了全部安装,默认是全部安装.

              ./bootstrap.sh --prefix=/usr/local/boost1.4

              这样会将头文件安装到 /usr/local/boost1.4/include

              库文件安装到 /usr/local/boost1.4/lib

              然后 

              ./bjam install

               注意不加install的话文件不会拷贝到你指定的安装路径的. 

             然后你可以设置一下环境变量,如BOOST_ROOT,BOOST_LIB

             下面我实验的时候直接写的安装路径,如 /usr/local/boost1.4/include

  • 直接用python,c 转换api 如何实现.

         看一个最简单的例子

         

复制代码
#include  < Python.h >
int
main(
int  argc,  char   * argv[])
{
Py_Initialize();
PyRun_SimpleString(
" from time import time,ctime\n "
" print 'Today is',ctime(time())\n " );
Py_Finalize();
return   0 ;
}
复制代码

       假设这个程序命名为a.cc,如何编译它呢.无外乎要能找到python的头文件和动态链接库.如下:

       g++ -I /usr/local/include/python2.6 -lpython2.6 -o a a.cpp

       ./a

        Today is Sun Nov 15 17:25:25 2009

  • boost.python的支持  

         使用boost.python需要以下步骤

 

  1. #include <boost/python.hpp>
  2. 调用Py_Initialize()  来开启解释器 并且生成  _main_ 模块 .
  3. 使用该解释器调用 Python C API .注意当前你一定不要最后调用Py_Finalize了结束解释器 ,这个问题可能会在以后版本中改掉. 当然你可以在这些步骤中有其它的C++代码.
     还是直接看代码吧,boost.python提供了3种调用python代码的方法,

     eval, exec, exec_file,

     分别对应 

     计算表达式值,

     执行python语句,

     执行python 文本如a.py.

     而boost::python::object的使用,使得调用python中的函数异常的简单.

     下面的代码,演示了exec,exec_file,object的使用,基本上覆盖了所有常见的需求.

      首先写一个简单的python 文件 ,

      simple.py

      

def  foo(i  =   4 ):
  
return  i  +   2008

 

      写一个C++的代码

      embedding.cc

 

复制代码
#include  < iostream >
using   namespace  std;
#include 
< boost / python.hpp >
using   namespace  boost::python;

int  main( int  argc,  char   * argv[])
{

  Py_Initialize();

  
object  main_module  =  import( " __main__ " );
  
object  main_namespace  =  main_module.attr( " __dict__ " );
  exec(
" hello = file('hello.txt', 'w')\n "
       
" hello.write('Hello world!')\n "
       
" hello.close() " ,
       main_namespace);
  exec(
" result = 5 ** 2 " , main_namespace);
  
int  five_squared  =  extract < int > (main_namespace[ " result " ]);
  cout 
<<   " The five_squeared caculated by python is  "   <<  five_squared  <<  endl;

   
//  Load the sys module.
   object  sys  =  import( " sys " );

  
//  Extract the python version.
  std:: string  version  =  extract < std:: string > (sys.attr( " version " ));
  std::cout 
<<  version  <<  std::endl;

 
 
// 要求simple.py与可执行文件在相同路径下! 运行ok
   object  simple  =  exec_file( " simple.py " ,main_namespace, main_namespace);
  
// dict global;
  
// object result = exec_file("simple.py", global, global);
   object  foo  =  main_namespace[ " foo " ];
  
int  val  =  extract < int > (foo( 5 ));
  cout 
<<   " Python has caculated foo as  "   <<  val  <<  endl;


  
return   0 ;
}
复制代码


 如何编译这个程序呢,其实就是能找的python, 以及boost.python的头文件和库文件.我采用了cmake,管理.

 最简单的在相同代码路径下,建立一个文件CMakeLists.txt,写入以下内容,注意你可能需要根据自己的安装路径进行

 更改.


复制代码
project(Embedding) #随便起一个工程名称

#boost.python,python头文件路径
include_directories(
/ usr / local / boost1. 4 / include  / usr / local / include / python2. 6 )

link_directories(
/ usr / local / boost1. 4 / lib  / usr / local / lib)  #boost.python,python动态链接库路径

add_executable (embedding embedding.cc)  #源文件embedding.cc 生成可执行文件embedding
target_link_libraries(embedding libboost_python.so libpython2.
6 .so) #可执行文件依赖与这两个库
复制代码

 

 如果你配置好环境变量,或者头文件库在默认的查找位置,或者应用ln可能不需要这么繁琐,但是这样是一个可行的方案.

cmake .

make

./embedding

         The five_squeared caculated by python is 25
   2.6.2 (r262:71600, Nov 14 2009, 14:18:33)
   [GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu4)]
   Python has caculated foo as 2013


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值