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