play with boost.python 2

background

in 1, we have a basic work flow of boost.python. in reality, the C++ project may have multi headers, where define many structs/classes, and include nested structs. here we give an simple example of nested struct/class.

api_header.hpp

1
2
3
4
5
6
7
8
9
typedef struct {
float time;
float dx ;
float dy ;
} AEB;
typedef struct {
AEB out1 ;
} OP;

aeb.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
#include "api_header.hpp"
class aeb {
public:
aeb() {}
OP op_out ;
void test_op(){
(void) memset((void *)&op_out, 0, sizeof(OP));
op_out.out1.time = 1.0 ;
op_out.out1.dx = 2.0 ;
op_out.out1.dy = 3.0 ;
AEB o1 = op_out.out1 ;
std::cout << o1.time << std::endl ;
}
};

for each of them, we can write a separate wrapp files.

api_wrapper.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <Python.h>
#include <boost/python.hpp>
#include "api_struct.h"
using namespace boost::python;
BOOST_PYTHON_MODULE(api_wrapper) {
class_<AEB>("AEB", "aeb struct")
.def_readwrite("time", &AEB::time)
.def_readwrite("dx", &AEB::dx)
.def_readwrite("dy", &AEB::dy) ;
class_<OP>("OP", "OP struct")
.def_readwrite("out1", &OP::out1);
}

aeb_wrapper.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <Python.h>
#include <boost/python.hpp>
#include "student.h"
using namespace boost::python;
BOOST_PYTHON_MODULE(aeb) {
scope().attr("__version__") = "1.0.0";
class_<aeb>("aeb", "a class of aeb ADAS")
.def(init<>())
.def(init<std::string, int>())
.def_readwrite("op_out", &aeb::op_out)
.def("test_op", &aeb::test_op, "test op")
}

compared to previous blog, we had def_readwrite() to include the nested struct in aeb python module, which is dynamic linked during python runtime, so which requires to import api_header module first, then import aeb module.

build && test

1
2
3
g++ -I/home/anaconda3/envs/aeb/include/python3.6m -I/usr/local/include/boost -fPIC wrap_api.cpp -L/usr/local/lib/ -lboost_python36 -shared -o wrap_api.so
g++ -I/home/anaconda3/envs/aeb/include/python3.6m -I/usr/local/include/boost -fPIC wrap_student.cpp -L/usr/local/lib/ -lboost_python36 -shared -o student.so
1
2
3
4
5
6
7
import wrap_api
import aeb
s = aeb.aeb()
s.test_op()
a = s.op_out.out1
a.time
a.dx

summary

this basic workflow is enough to package Matlab/Simulink ADAS models C++ code to Python test framework.