• 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
    
  • 相关阅读:
    2019自我剖析
    jzoj4640. 【GDOI2017模拟7.15】妖怪
    jzoj4649. 【NOIP2016提高A组模拟7.17】项链
    jzoj3171. 【GDOI2013模拟4】重心
    jzoj4673. 【NOIP2016提高A组模拟7.20】LCS again
    学习计算几何基础知识小结
    学习第一类斯特林数小记
    jzoj4213. 对你的爱深不见底
    jzoj4212. 【五校联考1day2】我想大声告诉你
    jzoj3085. 图的计数
  • 原文地址:https://www.cnblogs.com/silvermagic/p/9087477.html
Copyright © 2020-2023  润新知