Python calls C++ and makes Python interface through Pybind11

  • 2020-12-18 01:51:36
  • OfStack

I experimented with the ubuntu system, so it may be different from window.

python calls C/C++ there are many methods, such as ES8en.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.

1. Introduction to pybind11 and environmental installation

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 supports only compilers above python2.7 and C++ 11, making it more concise and efficient than ES32en.Python.

In order to use pybind11, we need to support the compiler of C++ 11 standard (GCC 4.8 and above, VS 2015 Update 3 and above) and python 2.7 and above. We also need to download CMake.

cmake tutorial can refer to: / / www ofstack. com article / 148903. htm

First of all, we from pybind11 github url: https: / / github com/pybind/pybind11 download the source code. Before cmake works, install pytest pip install pytest, otherwise it will make an error Compile and run the test cases with CMake:

 Enter the pybind11 The directory, 
cd tests
cmake ..
cmake --build . --config Release --target check

If all the test cases pass, the installation is successful.

2. python calls C++

After downloading and compiling pybind11, we can start to study the official pybind11 Tutorial. Please refer to the official documentation for detailed introductory tutorials and syntax. Here, we will briefly demonstrate how to write C++ module for python to call.
First, we write an C++ source file named ES82en.cpp


#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int i, int j)
{
 return i + j;
}
PYBIND11_MODULE(example, m)
{
 // optional module docstring
 m.doc() = "pybind11 example plugin";
 // expose add function, and add keyword arguments and default arguments
 m.def("add", &add, "A function which adds two numbers", py::arg("i")=1, py::arg("j")=2);
 // exporting variables
 m.attr("the_answer") = 42;
 py::object world = py::cast("World");
 m.attr("what") = world;
}

2.1 Compile using window

I don't have experiments, so I can refer to other tutorials

2.2 Compilation method of CMake

Of course, you can also compile with CMake. First write 1 CMakeLists.txt


cmake_minimum_required(VERSION 2.8.12)
project(example) 
add_subdirectory(pybind11)
pybind11_add_module(example example.cpp)

example.cpp is required to be placed in the same level 1 directory as pybind11 because we called es10106EN11 and example.cpp in CMakeLists.txt in the same directory. Executes under the current directory


cmake .
make

The example.es113EN-36ES114en-x86_64-ES116en-ES117en.so file is generated. This file is the one that python can call. Run python again in the same directory, and go to the python command line


import example
example.add(3, 4)
[out]: 7

3. Intermediate call

The above is a simple example, and sometimes the functionality we need can be quite complex.

Build model design library invocation problem.

For example, if your cpp file refers to other third party libraries, then the so file we generate may need to rely on the third party library.

The local ES135en.cpp file


#include <pybind11/pybind11.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <string>
namespace py = pybind11;
void read_img(std::string img_path)
{
 cv::Mat image = cv::imread(img_path, CV_LOAD_IMAGE_COLOR);
}
PYBIND11_MODULE(myopencv, m)
{
 m.def("read_img", &read_img, "get image size");
}

CMakeLists.txt can be written as follows


cmake_minimum_required(VERSION 2.8.12)
project(myopencv)
add_subdirectory(pybind11)
pybind11_add_module(myopencv myopencv.cpp)

Compiled by cmkae


cmake .
make

Generate the myopencv.cpython-36ES151en-ES152en86_64-ES153en-ES154en.so file
Call in python


import myopencv

So far, we have found something wrong here. It hasn't been adjusted yet

Data type mismatch problem

For example, opencv is the type of numpy in python, but c++ is the type of ES169en.Mat

For the type mismatch problem of opencv, the solution has been given on github.

cpp and h https file download address: / / github com/edmBernard/pybind11_opencv_numpy

You can search github for what you need, or do it yourself.

conclusion


Related articles: