boost.python将C++转化为Python接口

将C++的类转换为python

参考链接:https://www.boost.org/doc/libs/1_65_1/libs/python/doc/html/tutorial/index.html

成员函数

参考链接:https://www.boost.org/doc/libs/1_65_1/libs/python/doc/html/tutorial/tutorial/exposing.html

struct World
{
    void set(std::string msg) { this->msg = msg; }
    std::string greet() { return msg; }
    std::string msg;
};

包装成Python可调用函数

#include <boost/python.hpp>
using namespace boost::python;

BOOST_PYTHON_MODULE(hello)
{
    class_<World>("World")
        .def("greet", &World::greet)
        .def("set", &World::set)
    ;
}

构造函数

struct World
{
    World(std::string msg): msg(msg) {} // added constructor
    World(double,double);
    void set(std::string msg) { this->msg = msg; }
    std::string greet() { return msg; }
    std::string msg;
};

python的构造函数使用的是__init__,因此使用init来致命是类的构造函数

class_<World>("World", init<std::string>())
    .def(init<double, double>())
    .def("greet", &World::greet)
    .def("set", &World::set)
;

如果不想暴露类的构造函数,则使用class(“Abstract”, no_init)
,任何调用其构造函数都会报错,可以用在接口类中
_

成员变量

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

成员函数

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

类的属性

在c++中,成员变量具有不同的属性,但是在python中可以访问任何成员变量。如果向访问C++类中的成员变量,则需要通过getter和sertter函数。

struct Num
{
    Num();
    float get() const;
    void set(float value);
    ...
};

封装

class_<Num>("Num")
    .add_property("rovalue", &Num::get)
    .add_property("value", &Num::get, &Num::set);
>>> x = Num()
>>> x.value = 3.14
>>> x.value, x.rovalue
(3.14, 3.14)
>>> x.rovalue = 2.17 # error!

继承

以上的例子是对非多态类的封装,对于多态类的封装如下

struct Base { virtual ~Base(); };
struct Derived : Base {};
void b(Base*);
void d(Derived*);
Base* factory() { return new Derived; }

对于继承,则需指明继承对象;对于factory()返回派生类,则需要使用return_value_policy<manage_new_object>来让一个基类指针指向派生类指针。
对于

class_<Base>("Base")
class_<Derived, bases<Base> >("Derived")
def("b", b);
def("d", d);
def("factory", factory,return_value_policy<manage_new_object>());

普通函数

参考链接:https://www.boost.org/doc/libs/1_65_1/libs/python/doc/html/tutorial/tutorial/functions.html#tutorial.functions.default_arguments.boost_python_member_function_ove
对于C++来说会操作指针和引用等低级原语,在变成Python可调用是需要指明这些对象的周期。

X& f(Y& y, Z* z)
{
    y.z = z;
    return y.x;
}

1,2是参数的位置

def("f", f,return_internal_reference<1,with_custodian_and_ward<1, 2> >());

使用的政策是:

policy1<args...,
    policy2<args...,
        policy3<args...> > >

政策有如下,具体可参考链接:https://www.boost.org/doc/libs/1_65_1/libs/python/doc/html/reference/function_invocation_and_creation/models_of_callpolicies.html

policy说明
with_custodian_and_wardTies lifetimes of the arguments
with_custodian_and_ward_postcallTies lifetimes of the arguments and results
return_internal_referenceTies lifetime of one argument to that of result
return_value_policywith T one of
reference_existing_objectnaive (dangerous) approach
copy_const_referenceBoost.Python v1 approach
copy_non_const_reference
manage_new_objectAdopt a pointer and hold the instance

重载

struct X
{
    bool f(int a)
    {
        return true;
    }

    bool f(int a, double b)
    {
        return true;
    }

    bool f(int a, double b, char c)
    {
        return true;
    }

    int f(int a, int b, int c)
    {
        return a + b + c;
    };
};

bool    (X::*fx1)(int)              = &X::f;
bool    (X::*fx2)(int, double)      = &X::f;
bool    (X::*fx3)(int, double, char)= &X::f;
int     (X::*fx4)(int, int, int)    = &X::f;
.def("f", fx1)
.def("f", fx2)
.def("f", fx3)
.def("f", fx4)

也可以自动重载具有相同序列参数的函数

void foo()
{
   /*...*/
}

void foo(bool a)
{
   /*...*/
}

void foo(bool a, int b)
{
   /*...*/
}

void foo(bool a, int b, char c)
{
   /*...*/
}
BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3)
.def("foo", (void(*)(bool, int, char))0, foo_overloads());

默认参数

int f(int, double = 3.14, char const* = "hello");

手工

// write "thin wrappers"
int f1(int x) { return f(x); }
int f2(int x, double y) { return f(x,y); }

/*...*/

    // in module init
    def("f", f);  // all arguments
    def("f", f2); // two arguments
    def("f", f1); // one argument

自动

BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 2)//0-2个默认参数
def("f", f, f_overloads());

对于类中的成员函数

struct george
{
    void
    wack_em(int a, int b = 0, char c = 'x')
    {
        /*...*/
    }
};

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3)
.def("wack_em", &george::wack_em, george_overloads());
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页