視頻教程:
C++數(shù)據(jù)類型的導(dǎo)出和調(diào)用(上)
C++數(shù)據(jù)類型的導(dǎo)出和調(diào)用(下)
C++數(shù)據(jù)類型的導(dǎo)出的補(bǔ)充
boost::python用于將C++的函數(shù)和對象導(dǎo)出,方便python調(diào)用對象和方法屿聋,用來實(shí)現(xiàn)C++和Python的混合編程。
編譯boost::python庫和建立VS工程的詳細(xì)步驟參考boost::python實(shí)現(xiàn)C++和Python的混合編程(編譯和配置)
函數(shù)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()用于得到當(dāng)前的作用,定義新的scope對象會(huì)改變當(dāng)前的作用域
- 使用參數(shù)來構(gòu)造一個(gè)新的scope對象會(huì)將關(guān)聯(lián)的全局 python 對象更改為參數(shù)所持有的對象 直到作用域?qū)ο蟮纳嫫诮Y(jié)束, 關(guān)聯(lián)的全局 python 對象才會(huì)恢復(fù)到作用域?qū)ο笾暗膶ο蟆?/li>
- 官方解釋和例子
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.改變導(dǎo)出順序,也沒有問題,在模塊中加入常量屬性
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對象,則改變了當(dāng)前的作用域戒幔,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定義了新的域?qū)ο螅淖兞水?dāng)前的作用域诗茎,這個(gè)對象出了作用域,則會(huì)恢復(fù)為之前的域?qū)ο?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'
- 一個(gè)模塊里導(dǎo)出的類和原始的類必須一一對應(yīng)献汗,不能導(dǎo)出了多個(gè)類對應(yīng)一個(gè)類
Inheritance Classes
boost::python::class_<T, boost::python::bases<TBase>>("TName")
- 必須告知導(dǎo)出原C++類的繼承關(guān)系敢订,不然導(dǎo)出后類之間就沒有了繼承關(guān)系
-
告知類的繼承關(guān)系關(guān)系后:
- 繼承類自動(dòng)繼承了基類的Python方法(即包裝了的c++成員函數(shù))
- 即使是基類指針指向繼承類對象,多態(tài)的函數(shù)也能夠找到相應(yīng)繼承類的對應(yīng)函數(shù)
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);
//因?yàn)閒actory是生成一個(gè)新的Direved對象
//manage_new_object告知Python生成一個(gè)指針指向一個(gè)新生成的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>
- 如果需要擁有虛函數(shù)的類能在導(dǎo)出后供Python繼承楚午,則新建一個(gè)包裝類,它繼承于基類并且同時(shí)繼承boost::python::wrapper來對這個(gè)類進(jìn)行封裝尿招,導(dǎo)出的時(shí)候矾柜,實(shí)際上導(dǎo)出的是新建的這個(gè)類
- 包裝類VFObjWrapper里對虛函數(shù)進(jìn)行了規(guī)則處理,即調(diào)用是檢查繼承類里是否有虛函數(shù)的重寫就谜,如果沒有怪蔑,調(diào)用基類的虛函數(shù)(因?yàn)榛惖奶摵瘮?shù)有實(shí)現(xiàn))
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函數(shù)
>>> class newObj(Python_Wrapper.VFObj):
... def Func(self):
... return 88
...
>>> obj = newObj()
>>> obj.Func()
88
//新的繼承類沒有重現(xiàn)Func函數(shù),調(diào)用Func函數(shù)會(huì)調(diào)用基類的Func函數(shù)
>>> 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
- 如果需要****擁有****純虛函數(shù)的類能在導(dǎo)出后供Python繼承丧荐,則****新建一個(gè)包裝類饮睬,它繼承于基類并且同時(shí)繼承boost::python::wrapper來對這個(gè)類進(jìn)行封裝,導(dǎo)出的時(shí)候篮奄,實(shí)際上導(dǎo)出的是新建的這個(gè)類
- 包裝類PVFObjWrapper里對純虛函數(shù)進(jìn)行了規(guī)則處理捆愁,即調(diào)用的是繼承類的虛函數(shù)
- 導(dǎo)出是使用boost::python::pure_virtual告知哪個(gè)是純虛函數(shù)。
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 //構(gòu)造函數(shù)的可選參數(shù)標(biāo)識
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS //定義導(dǎo)出函數(shù)名窟却,最少參數(shù)和最多參數(shù)
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為最少參數(shù)昼丑,3為最多參數(shù)
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 //定義導(dǎo)出函數(shù)名,最少參數(shù)和最多參數(shù)
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描述導(dǎo)出智能指針夸赫,導(dǎo)入module時(shí)會(huì)報(bào)錯(cuò)
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
>>>
- 只導(dǎo)出智能指針菩帝,不導(dǎo)出智能指針指向的類,也會(huì)報(bào)錯(cuò)
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
函數(shù)返回值為引用的導(dǎo)出
- 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時(shí)同一個(gè)對象
函數(shù)返回值為靜態(tài)對象的導(dǎo)出
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
函數(shù)返回值為新對象的導(dǎo)出
- 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
模塊導(dǎo)出的類必須一一對應(yīng)
一個(gè)模塊里導(dǎo)出的類和原始的類必須一一對應(yīng)茬腿,不能導(dǎo)出了多個(gè)類對應(yīng)一個(gè)類
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