视频教程:
C++数据类型的导出和调用(上)
C++数据类型的导出和调用(下)
C++数据类型的导出的补充
boost::python用于将C++的函数和对象导出,方便python调用对象和方法,用来实现C++和Python的混合编程。
编译boost::python库和建立VS工程的详细步骤参考boost::python实现C++和Python的混合编程(编译和配置)
函数Function
boost::python::def()
char const* greet()
{
return "Hello world!";
}
BOOST_PYTHON_MODULE(boost_python)
{
boost::python::def("greet", greet);
}
//python
>>> import Python_Wrapper
>>> Python_Wrapper.greet()
'Hello world!'
Const
boost::python::scope().attr
- boost::python::scope()用于得到当前的作用,定义新的scope对象会改变当前的作用域
- 使用参数来构造一个新的scope对象会将关联的全局 python 对象更改为参数所持有的对象 直到作用域对象的生存期结束, 关联的全局 python 对象才会恢复到作用域对象之前的对象。
- 官方解释和例子
class Message
{
public:
void Set(std::string msg)
{
m_msg = msg;
}
std::string Get()
{
return m_msg;
}
private:
std::string m_msg;
};
//1.在模块中加入常量属性
BOOST_PYTHON_MODULE(boost_python)
{
//const
boost::python::scope().attr("yes") = 1;
boost::python::scope().attr("no") = 0;
boost::python::class_<Message>("Message")
.def("Set", &Message::Set)
.def("Get", &Message::Get);
}
//python
>>> import Python_Wrapper
>>> Python_Wrapper.yes
1
>>> Python_Wrapper.no
0
///////////////////////////////////////////////////////
//2.改变导出顺序,也没有问题,在模块中加入常量属性
BOOST_PYTHON_MODULE(boost_python)
{
boost::python::class_<Message>("Message")
.def("Set", &Message::Set)
.def("Get", &Message::Get);
//const
boost::python::scope().attr("yes") = 1;
boost::python::scope().attr("no") = 0;
}
//python
>>> import Python_Wrapper
>>> Python_Wrapper.yes
1
>>> Python_Wrapper.no
0
//////////////////////////////////////////////////////
//3.如果使用boost::python::scope对象,则改变了当前的作用域,yes和no成了message类的属性
BOOST_PYTHON_MODULE(boost_python)
{
//Change the current scope
boost::python::scope newScope = boost::python::class_<Message>("Message")
.def("Set", &Message::Set)
.def("Get", &Message::Get);
//const Defined in the current scope(Message)
boost::python::scope().attr("yes") = 1;
boost::python::scope().attr("no") = 0;
}
//python
>>> import Python_Wrapper
>>> Python_Wrapper.yes
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'Python_Wrapper' has no attribute 'yes'
>>> Python_Wrapper.no
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'Python_Wrapper' has no attribute 'no'
>>> msg = Python_Wrapper.Message()
>>> msg.yes
1
>>> msg.no
0
//4.使用boost::python::scope定义了新的域对象,改变了当前的作用域,这个对象出了作用域,则会恢复为之前的域对象
BOOST_PYTHON_MODULE(Python_Wrapper)
{
//const
{
boost::python::scope newScope = boost::python::class_<Message>("Message")
.def("Set", &Message::Set)
.def("Get", &Message::Get);
boost::python::scope().attr("yes") = 1;
boost::python::scope().attr("no") = 0;
}
boost::python::scope().attr("exist") = 1;
boost::python::scope().attr("none") = 0;
}
//python
>>> import Python_Wrapper
>>> msg = Python_Wrapper.Message()
>>> msg.yes
1
>>> msg.no
0
>>> Python_Wrapper.exist
1
>>> Python_Wrapper.none
0
Enum
boost::python::enum_<T>("TName")
enum MessageType
{
MT_START = 1,
MT_PROCESS,
MT_DONE,
MT_EXCEPTION
};
BOOST_PYTHON_MODULE(boost_python)
{
//enum
boost::python::enum_<MessageType>("MessageType")
.value("MT_START", MT_START)
.value("MT_PROCESS", MT_PROCESS)
.value("MT_DONE", MT_DONE)
.value("MT_EXCEPTION", MT_EXCEPTION);
}
//python
>>> import Python_Wrapper
>>> Python_Wrapper.MessageType.MT_START
Python_Wrapper.MessageType.MT_START
>>> int(Python_Wrapper.MessageType.MT_START)
1
>>> int(Python_Wrapper.MessageType.MT_DONE)
3
Struct
boost::python::class_<T>("TName")
struct StructionData
{
void hello()
{
std::cout << "hello, this is boost::python sample!" << std::endl;
}
void printmsg()
{
std::cout << "print message done!" << std::endl;
}
}
BOOST_PYTHON_MODULE(Python_Wrapper)
{
//struct
boost::python::class_<StructionData>("StructionData")
.def("hello", &StructionData::hello)
.def("printmsg", &StructionData::printmsg);
}
//python
>>> import Python_Wrapper
>>> data = Python_Wrapper.StructionData()
>>> data.hello()
hello, this is boost::python sample!
>>> data.printmsg()
print message done!
Class of Default Constructor
boost::python::class_<T>("TName")
class Message
{
public:
void Set(std::string msg)
{
m_msg = msg;
}
std::string Get()
{
return m_msg;
}
private:
std::string m_msg;
};
BOOST_PYTHON_MODULE(boost_python)
{
//class of default constructor
boost::python::class_<Message>("Message")
.def("Set", &Message::Set)
.def("Get", &Message::Get);
}
//python>>> import boost_python
>>> import Python_Wrapper
>>> msg = Python_Wrapper.Message()
>>> msg.Get()
''
>>> msg.Set('123')
>>> msg.Get()
'123'
Class of Custom Constructor
boost::python::class_<T>("TName", boost::python::init<para>())
class Sum
{
public:
Sum(std::string data) :m_data(data) {}
Sum(double a, double b) :m_a(a), m_b(b) {}
void Set(std::string data)
{
m_data = data;
}
std::string Get()
{
return m_data;
}
double Result()
{
return m_a + m_b;
}
private:
std::string m_data;
double m_a;
double m_b;
};
BOOST_PYTHON_MODULE(boost_python)
{
//class of custom constructor
boost::python::class_<Sum>("Sum", boost::python::init<std::string>())
.def(boost::python::init<double, double>())
.def("Set", &Sum::Set)
.def("Get", &Sum::Get)
.def("Result", &Sum::Result);
}
//python
>>> import Python_Wrapper
>>> s1 = Python_Wrapper.Sum()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
Sum.__init__(Sum)
did not match C++ signature:
__init__(struct _object * __ptr64, double, double)
__init__(struct _object * __ptr64, class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)
>>> s1 = Python_Wrapper.Sum("total")
>>> s1.Get()
'total'
>>> s2 = Python_Wrapper.Sum(1,2)
>>> s2.Result()
3.0
Data member of Class
.def_readonly()/.def_readwrite()
class User
{
public:
User(std::string name) :m_name(name), m_number(-1) {}
std::string m_name;
int m_number;
};
BOOST_PYTHON_MODULE(boost_python)
{
//data member of class
boost::python::class_<User>("User", boost::python::init<std::string>())
.def_readonly("name", &User::m_name)
.def_readwrite("number", &User::m_number);
}
//python
>>> import Python_Wrapper
>>> user = Python_Wrapper.User("Jason")
>>> user.name = "Micky"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>> user.number = 12345
>>> user.number
12345
Add Properties to Class
.add_property()
class MessagePro
{
public:
void Set(std::string msg)
{
m_msg = msg;
}
std::string Get()
{
return m_msg;
}
private:
std::string m_msg;
};
BOOST_PYTHON_MODULE(boost_python)
{
//add properties to class
boost::python::class_<MessagePro>("MessagePro")
.add_property("info", &MessagePro::Get, &MessagePro::Set);
}
//python
>>> import Python_Wrapper
>>> msg = Python_Wrapper.MessagePro()
>>> msg.set()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'MessagePro' object has no attribute 'set'
>>> msg.get()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'MessagePro' object has no attribute 'get'
>>> msg.info
''
>>> msg.info = 'hello'
>>> msg.info
'hello'
- 一个模块里导出的类和原始的类必须一一对应,不能导出了多个类对应一个类
Inheritance Classes
boost::python::class_<T, boost::python::bases<TBase>>("TName")
- 必须告知导出原C++类的继承关系,不然导出后类之间就没有了继承关系
-
告知类的继承关系关系后:
- 继承类自动继承了基类的Python方法(即包装了的c++成员函数)
- 即使是基类指针指向继承类对象,多态的函数也能够找到相应继承类的对应函数
class Base
{
public:
virtual ~Base() {};
virtual std::string Name()
{
return "Base";
}
};
class Derived : public Base
{
public:
std::string Name()
{
return "Derived";
}
};
void BaseName(Base *base)
{
std::cout << base->Name().c_str() << std::endl;
}
void DerivedName(Derived *derived)
{
std::cout << derived->Name().c_str() << std::endl;
}
Base *factory()
{
return new Derived();
}
BOOST_PYTHON_MODULE(boost_python)
{
//inherited
boost::python::class_<Base>("Base", boost::python::init<>())
.def("Name", &Base::Name);
boost::python::class_<Derived, boost::python::bases<Base>>("Derived")
.def("Name", &Derived::Name);
boost::python::def("BaseName", BaseName);
boost::python::def("DerivedName", DerivedName);
//因为factory是生成一个新的Direved对象
//manage_new_object告知Python生成一个指针指向一个新生成的Python对象,
boost::python::def("factory", factory, boost::python::return_value_policy<boost::python::manage_new_object>());
}
//python
>>> import Python_Wrapper
>>> obj = Python_Wrapper.factory()
>>> obj.Name()
'Derived'
>>> Python_Wrapper.BaseName(obj)
Derived
>>> Python_Wrapper.DerivedName(obj)
Derived
>>>
>>> objBase = Python_Wrapper.Base()
>>> objBase.Name()
'Base'
>>> Python_Wrapper.BaseName(objBase)
Base
>>> Python_Wrapper.DerivedName(objBase)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
Python_Wrapper.DerivedName(Base)
did not match C++ signature:
DerivedName(class Derived * __ptr64)
Virtual Functions
boost::python::wrapper
boost::python::class_<TBase, boost::noncopyable>
- 如果需要拥有虚函数的类能在导出后供Python继承,则新建一个包装类,它继承于基类并且同时继承boost::python::wrapper来对这个类进行封装,导出的时候,实际上导出的是新建的这个类
- 包装类VFObjWrapper里对虚函数进行了规则处理,即调用是检查继承类里是否有虚函数的重写,如果没有,调用基类的虚函数(因为基类的虚函数有实现)
class VFObj
{
public:
virtual ~VFObj() {};
virtual int Func() { return 0; }
};
class VFObjWrapper : public VFObj, public boost::python::wrapper<VFObj>
{
public:
int Func()
{
if (boost::python::override Func = this->get_override("Func"))
{
return Func();
}
return VFObj::Func();
}
int default_Func()
{
return this->VFObj::Func();
}
};
BOOST_PYTHON_MODULE(boost_python)
{
//virtual function
boost::python::class_<VFObjWrapper, boost::noncopyable>("VFObj")
.def("Func", &VFObj::Func, &VFObjWrapper::Func);
}
//python
>>> import Python_Wrapper
>>> objVF = Python_Wrapper.VFObj()
>>> objVF.Func()
0
//新的继承类重写了Func函数
>>> class newObj(Python_Wrapper.VFObj):
... def Func(self):
... return 88
...
>>> obj = newObj()
>>> obj.Func()
88
//新的继承类没有重现Func函数,调用Func函数会调用基类的Func函数
>>> class derivedObj(Python_Wrapper.VFObj):
... def newFunc():
... pass
...
>>> dObj = derivedObj()
>>> dObj.Func()
0
Pure Virtual Functions
boost::python::wrapper
boost::python::class_<TBase, boost::noncopyable>
boost::python::pure_virtual
- 如果需要****拥有****纯虚函数的类能在导出后供Python继承,则****新建一个包装类,它继承于基类并且同时继承boost::python::wrapper来对这个类进行封装,导出的时候,实际上导出的是新建的这个类
- 包装类PVFObjWrapper里对纯虚函数进行了规则处理,即调用的是继承类的虚函数
- 导出是使用boost::python::pure_virtual告知哪个是纯虚函数。
class PVFObj
{
public:
virtual ~PVFObj() {}
virtual int Func() = 0;
};
class PVFObjWrapper : public PVFObj, public boost::python::wrapper<PVFObj>
{
public:
int Func()
{
return this->get_override("Func")();
}
};
BOOST_PYTHON_MODULE(boost_python)
{
//pure virtual function
boost::python::class_<PVFObjWrapper, boost::noncopyable>("PVFObj")
.def("Func", boost::python::pure_virtual(&PVFObj::Func));
}
//python
>>> import Python_Wrapper
>>> obj = Python_Wrapper.PVFObj()
>>> obj.Func()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: Pure virtual function called
>>> class derivedObj(Python_Wrapper.PVFObj):
... def Func(self):
... return 88
...
>>> dObj = derivedObj()
>>> dObj.Func()
88
Operators and Special Functions of Class
.def(boost::python::self + boost::python::self);
class Operand
{
public:
Operand() :m_num(0) {}
Operand(int num) :m_num(num) {}
int num()
{
return m_num;
}
Operand& operator+(const Operand& other)
{
m_num += other.m_num;
return *this;
}
Operand& operator+(int num)
{
m_num += num;
return *this;
}
Operand& operator-(const Operand& other)
{
m_num -= other.m_num;
return *this;
}
Operand& operator-(int num)
{
m_num -= num;
return *this;
}
Operand& operator+=(const Operand& other)
{
return operator+(other);
}
Operand& operator+=(int num)
{
return operator+(num);
}
Operand& operator-=(const Operand& other)
{
return operator-(other);
}
Operand& operator-=(int num)
{
return operator-(num);
}
bool operator<(const Operand& other)
{
return (m_num < other.m_num);
}
int abs()
{
m_num = std::abs(m_num);
return m_num;
}
private:
int m_num;
};
std::ostream& operator<<(std::ostream& out, Operand opr)
{
out << opr.num();
return out;
}
BOOST_PYTHON_MODULE(boost_python)
{
//operator
boost::python::class_<Operand>("Operand", boost::python::init<>())
.def(boost::python::init<int>())
.def("num", &Operand::num)
.def(boost::python::self + boost::python::self)
.def(boost::python::self + int())
.def(boost::python::self - boost::python::self)
.def(boost::python::self - int())
.def(boost::python::self += boost::python::self)
.def(boost::python::self += int())
.def(boost::python::self -= boost::python::self)
.def(boost::python::self -= int())
.def(boost::python::self < boost::python::self)
.def("abs", &Operand::abs)
.def(str(boost::python::self));
}
//python
>>> import Python_Wrapper
>>> opr1 = Python_Wrapper.Operand(10)
>>> opr1.num()
10
>>> opr1 + 50
<Python_Wrapper.Operand object at 0x000002639BD5A9E0>
>>> opr1.num()
60
>>> opr2 = Python_Wrapper.Operand(30)
>>> opr2.num()
30
>>> opr1 - opr2
<Python_Wrapper.Operand object at 0x000002639BD5A9E0>
>>> opr1.num()
30
>>> opr1 -= opr2
>>> opr1.num()
0
>>> opr1 - 20
<Python_Wrapper.Operand object at 0x000002639BD5A9E0>
>>> opr1.num()
-20
>>> opr1 < opr2
True
>>> str(opr2)
'30'
Function Overloading
- 需要重载声明
class Calculator
{
public:
int Func(int a)
{
return a;
}
int Func(int a, int b)
{
return a + b;
}
int Func(int a, int b, int c)
{
return a + b - c;
}
};
//重载声明
int(Calculator::*Func1)(int) = &Calculator::Func;
int(Calculator::*Func2)(int, int) = &Calculator::Func;
int(Calculator::*Func3)(int, int, int) = &Calculator::Func;
BOOST_PYTHON_MODULE(boost_python)
{
//function overload of class
boost::python::class_<Calculator>("Calculator", boost::python::init<>())
.def("Func", Func1)
.def("Func", Func2)
.def("Func", Func3);
}
//python
>>> import Python_Wrapper
>>> calc = Python_Wrapper.Calculator()
>>> calc.Func(3)
3
>>> calc.Func(3, 4)
7
>>> calc.Func(3, 4, 10)
-3
>>> calc.Func(3, 4, 10, 15)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
Calculator.Func(Calculator, int, int, int, int)
did not match C++ signature:
Func(class Calculator {lvalue}, int, int, int)
Func(class Calculator {lvalue}, int, int)
Func(class Calculator {lvalue}, int)
Function's Default Parameters of Class
boost::python::optional //构造函数的可选参数标识
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS //定义导出函数名,最少参数和最多参数
class CalculatorPro
{
public:
CalculatorPro()
{
m_value = 0.0;
}
CalculatorPro(int a, double b = 2.0, int c = 10)
{
m_value = a + b + c;
}
double Func(int a, double b = 3.0, int c = 5)
{
return a + b - c;
}
double Value()
{
return m_value;
}
private:
double m_value;
};
//1为最少参数,3为最多参数
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(CalculatorPro_overloads, Func, 1, 3);
BOOST_PYTHON_MODULE(boost_python)
{
//function's default parameters of class
boost::python::class_<CalculatorPro>("CalculatorPro", boost::python::init<>())
.def(boost::python::init<int, boost::python::optional<double, int>>())
.def("Func", &CalculatorPro::Func, CalculatorPro_overloads())
.def("Value", &CalculatorPro::Value);
}
//python
>>> import Python_Wrapper
>>> calc = Python_Wrapper.CalculatorPro()
>>> calc.Value()
0.0
>>> calc1 = Python_Wrapper.CalculatorPro(10)
>>> calc1.Value()
22.0
>>> calc2 = Python_Wrapper.CalculatorPro(10, 30)
>>> calc2.Value()
50.0
>>> calc3 = Python_Wrapper.CalculatorPro(10, 30, 50)
>>> calc3.Value()
90.0
>>> calc4 = Python_Wrapper.CalculatorPro(10, 30, 50, 60)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
CalculatorPro.__init__(CalculatorPro, int, int, int, int)
did not match C++ signature:
__init__(struct _object * __ptr64, int)
__init__(struct _object * __ptr64, int, double)
__init__(struct _object * __ptr64, int, double, int)
__init__(struct _object * __ptr64)
>>>
>>> calc5 = Python_Wrapper.CalculatorPro()
>>> calc5.Func(10)
8.0
>>> calc5.Func(10, 2.0)
7.0
>>> calc5.Func(10, 2.0, 30)
-18.0
>>> calc5.Func(10, 2.0, 30, 40)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
CalculatorPro.Func(CalculatorPro, int, float, int, int)
did not match C++ signature:
Func(class CalculatorPro {lvalue}, int)
Func(class CalculatorPro {lvalue}, int, double)
Func(class CalculatorPro {lvalue}, int, double, int)
Function's Default Parameters
BOOST_PYTHON_FUNCTION_OVERLOADS //定义导出函数名,最少参数和最多参数
double FuncofDefaultParas(int a, double b = 2.0, double c = 3.0)
{
return a + b + c;
}
BOOST_PYTHON_FUNCTION_OVERLOADS(FuncofDefaultParas_overload, FuncofDefaultParas, 1, 3);
BOOST_PYTHON_MODULE(boost_python)
{
//function's default parameters
boost::python::def("FuncofDefaultParas", FuncofDefaultParas, FuncofDefaultParas_overload());
}
>>> import Python_Wrapper
>>> Func = Python_Wrapper.FuncofDefaultParas
>>> Func
<Boost.Python.function object at 0x000001E7F20511C0>
>>> Func(1)
6.0
>>> Func(1, 5)
9.0
>>> Func(1, 5, 10)
16.0
>>> Func(2, 5, 10, 3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
Python_Wrapper.FuncofDefaultParas(int, int, int, int)
did not match C++ signature:
FuncofDefaultParas(int)
FuncofDefaultParas(int, double)
FuncofDefaultParas(int, double, double)
Smart Pointer
boost::python::register_ptr_to_python<TP>()
class Data
{
public:
void Set(int data)
{
m_data = data;
}
int Get()
{
return m_data;
}
private:
int m_data;
};
//smart pointer defined
using DataPtr = std::shared_ptr<Data>;
//smart pointer object
DataPtr pData(new Data);
BOOST_PYTHON_MODULE(boost_python)
{
//smart point;
boost::python::class_<Data>("Data", boost::python::init<>())
.def("Set", &Data::Set)
.def("Get", &Data::Get);
boost::python::register_ptr_to_python<DataPtr>();
boost::python::scope().attr("pData") = pData;
}
//python
>>> import Python_Wrapper
>>> Python_Wrapper.pData.Get()
-842150451
>>> Python_Wrapper.pData.Set(12345)
>>> Python_Wrapper.pData.Get()
12345
- 不加入boost::python::register_ptr_to_python描述导出智能指针,导入module时会报错
BOOST_PYTHON_MODULE(boost_python)
{
//smart point;
boost::python::class_<Data>("Data", boost::python::init<>())
.def("Set", &Data::Set)
.def("Get", &Data::Get);
//boost::python::register_ptr_to_python<DataPtr>();
boost::python::scope().attr("pData") = pData
}
//import
>>> import Python_Wrapper
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
SystemError: initialization of Python_Wrapper raised unreported exception
>>>
- 只导出智能指针,不导出智能指针指向的类,也会报错
BOOST_PYTHON_MODULE(boost_python)
{
//smart point;
/*
boost::python::class_<Data>("Data", boost::python::init<>())
.def("Set", &Data::Set)
.def("Get", &Data::Get);
*/
boost::python::register_ptr_to_python<DataPtr>();
boost::python::scope().attr("pData") = pData
}
//python
>>> import Python_Wrapper
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
SystemError: initialization of Python_Wrapper raised unreported exception
函数返回值为引用的导出
- boost::python::return_value_policy<boost::python::reference_existing_object>()
- 本例也可以使用boost::python::return_internal_reference<>()
class A
{
public:
int value;
};
class B
{
public:
A a;
};
A& getA(B &b)
{
return b.a;
}
BOOST_PYTHON_MODULE(boost_python)
{
boost::python::class_<A>("A", boost::python::init<>())
.def_readwrite("value", &A::value);
boost::python::class_<B>("B", boost::python::init<>())
.def_readwrite("a", &B::a);
boost::python::def("getA", getA, boost::python::return_value_policy<boost::python::reference_existing_object>());
//boost::python::def("getA", getA, boost::python::return_internal_reference<1>());
}
//python
>>> import Python_Wrapper
>>> bObj = Python_Wrapper.B()
>>> aObj = Python_Wrapper.getA(bObj)
>>> aObj.value
0
>>> bObj.a.value = 10
>>> aObj.value
10
>>> aObj.value = 20
>>> bObj.a.value
20
//aObj指向和bObj的a时同一个对象
函数返回值为静态对象的导出
boost::python::return_value_policy<boost::python::reference_existing_object>()
class D
{
public:
int value;
};
D& getStaticD()
{
static D d;
d.value = 10;
return d;
}
BOOST_PYTHON_MODULE(boost_python)
{
boost::python::class_<D>("D", boost::python::init<>())
.def_readwrite("value", &D::value);
boost::python::def("getD", getStaticD, boost::python::return_value_policy<boost::python::reference_existing_object>());
}
>>> import Python_Wrapper
>>> dObj = Python_Wrapper.getD()
>>> dObj.value
10
>>> dObj.value = 20
>>> dObj.value
20
函数返回值为新对象的导出
- boost::python::return_value_policy<boost::python::manage_new_object>()
class C
{
public:
int value;
};
C* getC()
{
return new C();
}
BOOST_PYTHON_MODULE(boost_python)
{
boost::python::class_<C>("C", boost::python::init<>())
.def_readwrite("value", &C::value);
boost::python::def("getC", getC, boost::python::return_value_policy<boost::python::manage_new_object>());
}
//python
>>> import Python_Wrapper
>>> cObj = Python_Wrapper.getC()
>>> cObj.value = 10
>>> cObj.value
10
模块导出的类必须一一对应
一个模块里导出的类和原始的类必须一一对应,不能导出了多个类对应一个类
class E
{
public:
int value;
};
BOOST_PYTHON_MODULE(boost_python)
{
boost::python::class_<E>("E", boost::python::init<>())
.def_readwrite("value", &E::value);
boost::python::class_<E>("EClone", boost::python::init<>())
.def_readwrite("value", &E::value);
}
//python
>>> import Python_Wrapper