Boost Python官方样例(二)

返回值

使用return_by_value有点像C++ 11的auto关键字,可以让模板自适应返回值类型(返回值类型必须是要拷贝到新的python对象的任意引用或值类型),可以使用return_by_value替换copy_const_referencecopy_non_const_referencemanage_new_objectreference_existing_object

返回常量对象引用

编写C++函数实现

$ vim ref.h
struct Bar { int x; };

struct Foo {
   Foo(int x) { b.x = x; }
   Bar const& get_bar() const { return b; }
 private:
   Bar b;
};

编写Boost.Python文件

$ vim ref_wrapper.cpp
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include "ref.h"

// Wrapper code
using namespace boost::python;
BOOST_PYTHON_MODULE(ref_ext)
{
        class_<Bar>("Bar")
                .def_readwrite("x", &Bar::x);

        class_<Foo>("Foo", init<int>())
                .def("get_bar", &Foo::get_bar
                , return_value_policy<copy_const_reference>());
}

运行python测试库文件

$ python
>>> import ref_ext
>>> f = ref_ext.Foo(2)
>>> b = f.get_bar()
>>> b.x
2

返回对象引用

编写C++函数实现

$ vim ref.cpp
struct Bar { int x; };

struct Foo {
   Foo(int x) { b.x = x; }
   Bar& get_bar() { return b; }
 private:
   Bar b;
};

编写Boost.Python文件

$ vim ref_wrapper.cpp
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/copy_const_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include "ref.h"

// Wrapper code
using namespace boost::python;
BOOST_PYTHON_MODULE(ref_ext)
{
        class_<Bar>("Bar")
                .def_readwrite("x", &Bar::x);

        class_<Foo>("Foo", init<int>())
                .def("get_bar", &Foo::get_bar
                , return_value_policy<copy_non_const_reference>());
}

运行python测试库文件

$ python
>>> import ref_ext
>>> f = ref_ext.Foo(3)
>>> b = f.get_bar()
>>> b.x
3

返回堆对象

编写C++函数实现

$ vim ref.h
#include <iostream>

struct Foo {
    Foo(int v) : x(v) {}
    ~Foo() { std::cout << "Foo destructor" << std::endl; }
    int x;
};

Foo* make_foo(int x) { return new Foo(x); }

编写Boost.Python文件

$ vim ref_wrapper.cpp
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/args.hpp>
#include <boost/python/class.hpp>
#include <boost/python/manage_new_object.hpp>
#include <boost/python/return_value_policy.hpp>
#include "ref.h"

// Wrapper code
using namespace boost::python;
BOOST_PYTHON_MODULE(ref_ext)
{
    def("make_foo", make_foo, return_value_policy<manage_new_object>());
    class_<Foo>("Foo", init<int>())
        .def_readwrite("x", &Foo::x);
}

运行python测试库文件

$ python
>>> import ref_ext
>>> f = ref_ext.make_foo(3)
>>> f.x
3

返回静态对象

编写C++函数实现

$ vim ref.h
#include <utility>

struct Singleton
{
   Singleton() : x(0) {}

   int exchange(int n)  // set x and return the old value
   {
        std::swap(n, x);
        return n;
   }

   int x;
};

Singleton& get_it()
{
   static Singleton just_one;
   return just_one;
}

编写Boost.Python文件

$ vim ref_wrapper.cpp
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/reference_existing_object.hpp>
#include <boost/python/return_value_policy.hpp>
#include "ref.h"

using namespace boost::python;
BOOST_PYTHON_MODULE(ref_ext)
{
    def("get_it", get_it, return_value_policy<reference_existing_object>());

    class_<Singleton>("Singleton")
       .def("exchange", &Singleton::exchange);
}

运行python测试库文件

$ python
>>> import ref_ext
>>> s1 = ref_ext.get_it()
>>> s2 = ref_ext.get_it()
>>> id(s1) == id(s2)
False
>>> s1.exchange(42)
0
>>> s2.exchange(99)
42

枚举

创建工程目录

$ mkdir Lesson5
$ cd Lesson5

编写C++函数实现

$ vim enum.h
enum color { red = 1, green = 2, blue = 8 };

编写Boost.Python文件

$ vim enum_wrapper.cpp
#include <boost/python.hpp>
#include "enum.h"

BOOST_PYTHON_MODULE(enum_ext)
{
    using namespace boost::python;
    enum_<color>("color")
        .value("red", red)
        .value("green", green)
        .value("blue", blue);
}

为库编写CMakeLists.txt

$ vim CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(enum)

### 此处的动态库名必须和BOOST_PYTHON_MODULE()中定义的保持一致,即最后生成的库必须名为enum_ext.so
set(enumSRC enum_wrapper.cpp)
add_library(enum_ext SHARED ${enumSRC})
set_target_properties(enum_ext PROPERTIES PREFIX "")

#dependencies
INCLUDE(FindPkgConfig)
pkg_check_modules(PYTHON REQUIRED python)
include_directories(/usr/include ${PYTHON_INCLUDE_DIRS})
target_link_libraries(enum_ext boost_python)

编译库

$ mkdir build
$ cd build
$ cmake ..
$ make

运行python测试库文件

### 在build目录下执行,即enum_ext.so存在的目录(可以将so移至其他目录,这样就可以在其他目录下打开python终端)
$ python
>>> import enum_ext
>>> help(enum_ext)
>>> enum_ext.color
<class 'enum_ext.color'>
>>> int(enum_ext.color.red)
1
>>> int(enum_ext.color.blue)
8
posted @ 2018-05-25 11:05  银魔术师  阅读(1460)  评论(0编辑  收藏  举报