use boost.python to Warp C++ for python

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010598445/article/details/52756673

在python中调用c++

c++ 速度快,python 比较方便,如果同时用到python和c++中库,则需要相互调用。目前python发展迅速,很多新库都以python为主,但一些传统或者强调速度的库依然是用c++写的。因此掌握这一技能,可以加速开发,避免重复地制造车轮。

介绍

在python中调用c++的方法很多,出名的有swig, boost.python,个人属于刚入门,由于对boost库有好感,觉得代表着c++方面最先进的技术。boost.python的理念也很好,不用去学习接口语言,不用修改源代码,直接快速上手。

官方文档

写一个小测试

  • cpp.cpp: c++源文件
  • py.py: python 测试文件
  • Jamroot: boost.python 配置文件

安装boost环境

sudo apt-get install libboost-all-dev

再下载一个boost 源代码,这样可以进行下面的官方测试并得到配置文件Jamroot

官方测试

  • hello world
  • cd /home/yzbx/Downloads/boost_1_61_0/libs/python/example/tutorial
  • bjam
warning: mismatched versions of Boost.Build engine and core
warning: Boost.Build engine (bjam) is 2014.03.00
warning: Boost.Build core (at /media/yzbx/NewPartition/home/yzbx/Downloads/boost_1_61_0/tools/build/src) is 2015.07-git
notice: no Python configured in user-config.jam
notice: will use default configuration
warning: No toolsets are configured.
warning: Configuring default toolset "gcc".
warning: If the default is wrong, your build may not work correctly.
warning: Use the "toolset=xxxxx" option to override our guess.
warning: For more configuration options, please consult
warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html
Performing configuration checks

    - 32-bit                   : no  (cached)
    - 64-bit                   : yes (cached)
    - arm                      : no  (cached)
    - mips1                    : no  (cached)
    - power                    : no  (cached)
    - sparc                    : no  (cached)
    - x86                      : yes (cached)
    - symlinks supported       : yes (cached)
...patience...
...patience...
...found 1833 targets...
  • python hello.py
hello, world
  • 官方测试目录,输出一大堆如bin,xxx.so
$: tree /home/yzbx/Downloads/boost_1_61_0/libs/python/example/tutorial
/home/yzbx/Downloads/boost_1_61_0/libs/python/example/tutorial
├── bin
│   ├── config.log
│   ├── gcc-5.4.0
│   │   └── debug
│   │       ├── hello_ext.so
│   │       └── hello.o
│   ├── hello.test
│   │   └── gcc-5.4.0
│   │       └── debug
│   │           ├── hello
│   │           ├── hello.output
│   │           └── hello.test
│   └── project-cache.jam
├── hello.cpp
├── hello_ext.so
├── hello.py
├── Jamroot
├── libboost_python.so -> libboost_python.so.1.61.0
├── libboost_python.so.1 -> libboost_python.so.1.61.0
├── libboost_python.so.1.61 -> libboost_python.so.1.61.0
└── libboost_python.so.1.61.0
  • 上面的命令运行成功,说明安装boost.python环境成功!

在ubuntu16.04上基于官方测试进行更改

  1. struct or class ? 写c++一般用class,不过用class就要加public,否则默认为private就无法在python中调用。
  2. bjam 如何使用配置?
Simply copy the file and tweak use-project boost to where your boost root directory is and you're OK.

The comments contained in the Jamrules file above should be sufficient to get you going. 

上面说只要指定boost的根目录,再按Jamroot中的注释去更改就okay!
这里写图片描述
3. 如上图,在个人测试文件夹下有三个文件:cpp.cpp,py.py,Jamroot,将root根目录设置为/home/yzbx/Downloads/boost_1_61_0, 再将python 模块名改为yzbx_ext,再将源文件和测试文件改为cpp.cpp,py.py, 并将测试输出目录改为yzbx
4. 个人测试文件的输出,通过对比,不难了解各个参数的含义

$: tree ~/test/boost-python/
/home/yzbx/test/boost-python/
├── bin
│   ├── config.log
│   ├── gcc-5.4.0
│   │   └── debug
│   │       ├── cpp.o
│   │       └── yzbx_ext.so
│   ├── project-cache.jam
│   └── yzbx.test
│       └── gcc-5.4.0
│           └── debug
│               ├── yzbx
│               ├── yzbx.output
│               └── yzbx.test
├── cpp.cpp
├── Jamroot
├── libboost_python.so -> libboost_python.so.1.61.0
├── libboost_python.so.1 -> libboost_python.so.1.61.0
├── libboost_python.so.1.61 -> libboost_python.so.1.61.0
├── libboost_python.so.1.61.0
├── py.py
└── yzbx_ext.so

附件

cpp.cpp

//  Copyright Joel de Guzman 2002-2004. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt
//  or copy at http://www.boost.org/LICENSE_1_0.txt)
//  Hello World Example from the tutorial
//  [Joel de Guzman 10/9/2002]

#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>


char const* greet()
{
   return "hello, world";
}

int add(int a,int b){
    return a+b;
}

struct bgs{
void set(int a){this->a=a;}
int getA(){return a;}
    int a;
};

class Var
{
public:
    Var(std::string name) : name(name), value() {}
    std::string const name;
    float value;
};

BOOST_PYTHON_MODULE(yzbx_ext)
{
    using namespace boost::python;
    def("greet", greet);
    def("add",add);
    class_<bgs>("bgs")
        .def("set",&bgs::set)
        .def("getA",&bgs::getA)
        .def_readonly("a",&bgs::a)
    ;

    class_<Var>("Var", init<std::string>())
    .def_readonly("name", &Var::name)
    .def_readwrite("value", &Var::value);
}

py.py

#  Copyright Joel de Guzman 2002-2007. Distributed under the Boost
#  Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt
#  or copy at http://www.boost.org/LICENSE_1_0.txt)
#  Hello World Example from the tutorial

import yzbx_ext
print yzbx_ext.greet()
print yzbx_ext.add(3,5)
bgs=yzbx_ext.bgs()
bgs.set(10)
print bgs.getA()
var=yzbx_ext.Var("pi")
var.value=3.14
print var.name,' is around ', var.value

Jamroot

# Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

import python ;

if ! [ python.configured ]
{
    ECHO "notice: no Python configured in user-config.jam" ;
    ECHO "notice: will use default configuration" ;
    using python ;
}

# Specify the path to the Boost project.  If you move this project,
# adjust this path to refer to the Boost root directory.
use-project boost
  : /home/yzbx/Downloads/boost_1_61_0 ;

# Set up the project-wide requirements that everything uses the
# boost_python library from the project whose global ID is
# /boost/python.
project
  : requirements <library>/boost/python//boost_python 
                 <implicit-dependency>/boost//headers 
  : usage-requirements <implicit-dependency>/boost//headers 
  ;

# Declare the three extension modules.  You can specify multiple
# source files after the colon separated by spaces.
python-extension yzbx_ext : cpp.cpp ;

# Put the extension and Boost.Python DLL in the current directory, so
# that running script by hand works.
install convenient_copy 
  : yzbx_ext 
  : <install-dependencies>on <install-type>SHARED_LIB <install-type>PYTHON_EXTENSION 
    <location>. 
  ;

# A little "rule" (function) to clean up the syntax of declaring tests
# of these extension modules.
local rule run-test ( test-name : sources + )
{
    import testing ;
    testing.make-test run-pyd : $(sources) : : $(test-name) ;
}

# Declare test targets
run-test yzbx : yzbx_ext py.py ;

猜你喜欢

转载自blog.csdn.net/u010598445/article/details/52756673