Weitere ähnliche Inhalte Ähnlich wie Boost.Python - domesticating the snake (20) Mehr von Sławomir Zborowski (9) Kürzlich hochgeladen (20) Boost.Python - domesticating the snake4. C++ vs Python
C++ Python
statically typed dynamically typed
strongly typed strongly typed
federation of languages object oriented
efficient flexible
compiled interpreted
manual memory
management
garbage collected
hard? easy
7. Why Boost.Python?
→ raw, C, reference counting ☹
→ custom tools, custom language ☹
→ custom tools, custom language ☹
→ easy, only C++ ☺
Python API
SWIG
SIP
Boost.Python
13. Exposing classes
1structResult{
2 longvalue=0;
3 staticResultcreate(longconstvalue){
4 returnResult{value};
5 }
6private:
7 explicitResult(longconstvalue):value(value){}
8};
9
10classCalculator{
11 std::unordered_map<long,Result>cache_;
12public:
13 Resultcalculate(longconstcoeff){
14 if(cache_.find(coeff)==cache_.end()){
15 Resultr=Result::create(42);//...
16 cache_.insert(std::make_pair(coeff,r));
17 }
18 returncache_.find(coeff)->second;
19 }
20};
15. Exposing classes
explicit exposure
member functions: d e f
member variables: d e f _ r e a d o n l y , d e f _ r e a d w r i t e
c-tors: n o _ i n i t , i n i t (multiple allowed)
properties: a d d _ p r o p e r t y (ro/rw)
17. Inheritance
65 bp::class_<Base>("Base")
66 .def("virtualMethod",&Base::virtualMethod)
67 .def("normalMethod",&Base::normalMethod)
68 ;
69
70 bp::class_<Derived,bp::bases<Base>>("Derived");
71
72 bp::def("createDerived",createDerived,
73 bp::return_value_policy<bp::manage_new_object>());
74}
1frombuild.CppUsersWroclawimport*
2
3b=createDerived()
4
5b.virtualMethod()
6b.normalMethod()
szborowsatprobookin~/D/p/b/code
↪pythontest3.py
Derived::virtualMethod
Base::normalMethod
18. Special methods
7template<typenameT>
8structVector{
9 Vector(Tx,Ty,Tz)
10 :x(x),y(y),z(z){}
11
12 Tx={},y={},z={};
13
14 Vector&operator+=(Vectorconst&other){
15 std::cout<<"Vector::operator+=n";
16 x+=other.x;
17 y+=other.y;
18 z+=other.z;
19 return*this;
20 }
21
22 Vectoroperator+(Vectorconst&other){
23 std::cout<<"Vector::operator+n";
24 returnVector{
25 x+other.x,
26 y+other.y,
27 z+other.z};
28 }
29
30};
19. Special methods
29 bp::class_<Vector<float>>("Vector",bp::init<float,float,float>())
30 .def_readonly("x",&Vector<float>::x)
31 .def_readonly("y",&Vector<float>::y)
32 .def_readonly("z",&Vector<float>::z)
33 .def(bp::self+bp::other<Vector<float>>{})
34 .def(bp::self+=bp::other<Vector<float>>{})
35 ;
1frombuild.CppUsersWroclawimport*
2
3v1=Vector(1.0,2.0,3.0)
4v2=Vector(2.0,3.0,4.0)
5
6v3=v1+v2
7v2+=v1
szborowsatprobookin~/D/p/b/code
↪pythontest4.py
Vector::operator+
Vector::operator+=
20. Special methods
C++ Python
o p e r a t o r + _ _ a d d _ _
_ _ r a d d _ _
o p e r a t o r - _ _ s u b _ _
o p e r a t o r + = _ _ i a d d _ _
o p e r a t o r - = _ _ i s u b _ _
o p e r a t o r < _ _ l t _ _
o p e r a t o r < = _ _ l e _ _
b p : : s t r _ _ s t r _ _
b p : : a b s _ _ a b s _ _
b p : : p o w _ _ p o w _ _
source: [python operators]
21. Exposing constants & enums
60constexprautoFAMOUS_CONSTANT=42;
61
62enumclassRole{
63 JuniorDev,
64 Dev,
65 SeniorDev,
66 ForgottenEmployee
67};
92 bp::scope().attr("FAMOUS_CONSTANT")=FAMOUS_CONSTANT;
93
94 bp::enum_<Role>("Role")
95 .value("JuniorDev",Role::JuniorDev)
96 .value("Dev",Role::Dev)
97 .value("SeniorDev",Role::SeniorDev)
98 .value("ForgottenEmployee",Role::ForgottenEmployee)
99 ;
22. Exposing constants & enums
1frombuild.CppUsersWroclawimport*
2
3printFAMOUS_CONSTANT
4
5role=Role.ForgottenEmployee
6printrole,'=',int(role)
szborowsatprobookin~/D/p/b/code
↪pythontest5.py
42
ForgottenEmployee=3
27. Interchanging objects
Python C++
i n t ,
f l o a t ,
b o o l , …
i n t , f l o a t ,
b o o l , …
o b j e c t o b j e c t
l i s t b p : : l i s t
d i c t b p : : d i c t
s t r b p : : s t r
l o n g b p : : l o n g _
* b p : : e x t r a c t < >
collections → indexing suites
custom types → converters
⇒
29. Embedding Python in C++
9intmain(){
10 Py_Initialize();
11 automainModule=bp::import("__main__");
12 automainNamespace=mainModule.attr("__dict__");
13
14 mainNamespace["messageFromCpp"]="I'mstringfromC++!"s;
15
16 try{
17 bp::exec(R"^(
18printmessageFromCpp
19response='HelloC++!Ialsosupportstrings;)'
20 )^",mainNamespace);
21 stringresponse=bp::extract<string>(mainNamespace["response"]);
22 cout<<response<<endl;
23 }
24 catch(bp::error_already_set){
25 PyErr_Print();
26 }
27}
szborowsatprobookin~/D/p/b/code
↪./embedded_python
I'mstringfromC++!
HelloC++!Ialsosupportstrings;)