Use pybind11 to encapsulate the C++ structure as a parameter of the function implementation steps

  • 2020-07-21 09:32:18
  • OfStack

python calls C/C++ there are many methods, such as ES4en.python, swig, ctypes, pybind11 and so on, these methods have complex and simple, but the advantage of pybind11 is to C++ 11 support is very good, API is relatively simple, now we simply note Pybind11 entry operation.

pybind11 profile

pybind11 is a lightweight library include the header file, it is mainly used on the basis of the existing C + + code extension, its syntax and goal very like Boost. Python, but Boost Python to all compatible with the existing basic C + + compiler and become very complex and huge, and thus the cost is a lot of obscure templates skills and a lot of unnecessary support for older version of the compiler. Pybind11 abandons these supports and only supports compilers above python2.7 and C++ 11, making it more concise and efficient than ES28en.Python.

In C, a structure (struct) refers to a data structure and a class of aggregated data types (aggregate data type) in C. Structures can be declared as variables, Pointers, arrays, and so on to implement more complex data structures. The struct is also a collection of 1 elements called members of the struct (member), which can be of different types, and members 1 are generally accessed by name.

Structure and pointer to structure are widely used as parameters of functions. This paper introduces how to use pybind11 to encapsulate C++ structure as parameters of functions.

1. Demand analysis

Existing structures, called student has 5 member variable name, Chinese, Mathematics, English and total, constructor generated by name instance, member function setName can for instance name assignment; The calc function takes one instance of student as a parameter and calculates the total score of total based on the scores of three courses. Encapsulate student, calc into an python module (abctest) containing an student class and an calc function.

2. Implementation steps

Define the student structure in the header file and declare the calc function. func. cpp function is implemented in C++ source file. Write pybind11 wrapper function; Write setup script with python; Compile and generate dynamic link library. Test function functionality.

3. Code implementation

Define the student structure in the header file and declare the calc function


// The file name: whjy.h
#include <string> 
using namespace std; 
struct student{ 
 string name; 
 int Chinese; 
 int Mathematics; 
 int English; 
 int total; 
 student(string n){ 
 this->name = n; 
 } 
 void setName(string stuName){ 
  this->name = stuName; 
 } 
}; 
void calc(struct student&);

func.cpp function is implemented in C++ source file


// The file name: func.cpp
#include "whjy.h" 
#include <string> 
void calc(struct student& tyh){ 
 tyh.total = tyh.Chinese + tyh.Mathematics + tyh.English; 
}

Write pybind11 wrapper functions


// The file name: func_wrapper.cpp
#include <pybind11/pybind11.h> 
#include "whjy.h" 
namespace py = pybind11; 
PYBIND11_MODULE(abctest, m){ 
 m.doc() = "simple example"; 
 
 py::class_<student>(m, "student") 
  .def(py::init<string>()) 
  .def("setName", &student::setName) 
  .def_readonly("name", &student::name) 
  .def_readwrite("Chinese", &student::Chinese) 
  .def_readwrite("Mathematics", &student::Mathematics) 
  .def_readwrite("English", &student::English) 
  .def_readwrite("total", &student::total); 
 m.def("calc", &calc); 
}

Write setup scripts with python


# The file name: setup.py
from setuptools import setup, Extension 
 
functions_module = Extension( 
 name = 'abctest', 
 sources = ['func.cpp', 'func_wrapper.cpp'], 
 include_dirs = [r'D:\software\pybind11-master\include', 
     r'D:\software\Anaconda\include'] 
) 
 
setup(ext_modules = [functions_module])

Compile to generate dynamic link libraries

Execute from the command line python setup.py build_ext --inplace , generate the pyd dynamic library under the current path.

Test function function


# The file name: test.py
import abctest 
s = abctest.student(" Xiao Ming ") 
s.Chinese = 100 
s.Mathematics = 110 
s.English =120 
abctest.calc(s) 
print(s.name + ":" + str(s.total) + " points ") 
print("----------------------") 
s.setName(" The little red ") 
print(s.name + ":" + str(s.total) + " points ")
[

output:
Xiaoming: 330
----------------------
Xiao Hong: 330 points

]

conclusion


Related articles: