【PyBind11】Python+C++接口,模型部署优化神器

目录

访问struct/class的公有非成员

如果private 用魔法方法,或者返回值是一个引用&

添加const

使用c++函数

如果碰到需要返回引用的

初始化写法

默认参数的写法

在 Python 中重写虚函数

自动监听变化

vscode环境变量

扫描二维码关注公众号,回复: 14229511 查看本文章

pybind11debug环境变量

奇奇怪怪的问题,初始化为0的mat会有杂像素,需要确保numpy类型正确

绑定exception

访问struct/class的公有非成员

对于公有非成员变量,非private的访问,pybind11提供了def_readwrite()方法来支持。具体定义如下

py::class_<Pet>(m, "Pet")
    .def(py::init<const std::string &>())
    .def_readwrite("name", &Pet::name)

如果private 用魔法方法,或者返回值是一个引用&

py::class_<Pet>(m, "Pet")
    .def(py::init<const std::string &>())
    .def_property("name", &Pet::getName, &Pet::setName)
    // ... remainder ...



const T Angle() const { return angle_; }
T &Angle() { return angle_; }


.def_property("Angle",
    py::cpp_function(overload_cast_<>()(&AngleAxisd::Angle),
                    py::return_value_policy::reference),
    py::cpp_function([](AngleAxisd &self, double angle) {
        self.Angle() = angle;
    }))

添加const

struct Pet {
    Pet(const std::string &name, int age) : name(name), age(age) { }

    void set(int age_) { age = age_; }
    void set(const std::string &name_) const { name = name_; }

    std::string name;
    int age;
};

template <typename... Args>
using overload_cast_ = pybind11::detail::overload_cast_impl<Args...>;

py::class_<Pet>(m, "Pet")
    .def("foo", overload_cast_<int>()(&Pet::set), "Set the pet's age")
    .def("foo", overload_cast_<const std::string &>()(&Pet::set,py::_const), "Set the pet's name");

使用c++函数

py::cpp_function func_cpp() {
    return py::cpp_function([](int i) { return i+1; },
       py::arg("number"));
}

func_cpp(number=2)
3

如果碰到需要返回引用的

/* Function declaration */
Data *get_data() { return _data; /* (pointer to a static data structure) */ }
...

/* Binding code */
m.def("get_data", &get_data); // <-- KABOOM, will cause crash when called from Python

# right
m.def("get_data", &get_data, py::return_value_policy::reference);

初始化写法

LineSegment(const std::string &current_space = "image");
LineSegment(const math::Vector2d &p1, const math::Vector2d &p2,
                const std::string &current_space = "image");


py::class_<LineSegment, Curve2d, std::shared_ptr<LineSegment>>(
    m, "LineSegment")
    .def(py::init<const std::string &>(),
            py::arg("current_space") = "image")
    .def(py::init<const math::Vector2d &, const math::Vector2d &,
                    const std::string &>(),
            py::arg("p1"), py::arg("p2"), py::arg("current_space") = "image")

默认参数的写法

void DrawLineSegment(image::Image &image, const shape2d::LineSegment &segment,
                     const std::vector<int> &color = std::vector<int>{128},
                     int thickness = 1);

    m.def("DrawRect", &DrawRect, "draw rect to image", py::arg("image"),
          py::arg("rect"), py::arg("color") = std::vector<int>{128},
          py::arg("thickness") = 1);

在 Python 中重写虚函数

因为py::_class默认是std::unique_ptr<Type>,如果类中有需要使用到shared_ptr那就要在继承类上加一个std::shared_ptr<Type>

Smart pointers — pybind11 documentation

class Shape2d
{
public:

    Shape2d(const std::string &current_space = "image");

    virtual ~Shape2d() = default;

    virtual double GetArea() const = 0;

    virtual std::shared_ptr<Shape2d>
    MapShape(const math::Affine2d &dst_from_src) const = 0;

public:
    std::string current_space;
};

class PyShape2d : public Shape2d
{
public:
    using Shape2d::Shape2d; // Inherit constructors 内部继承初始化
    double GetArea() const override
    {
        PYBIND11_OVERRIDE_PURE(double, Shape2d, GetArea, );
    }
    std::shared_ptr<Shape2d>
    MapShape(const math::Affine2d &dst_from_src) const override
    {
        PYBIND11_OVERRIDE_PURE(std::shared_ptr<Shape2d>, Shape2d, MapShape,
                               dst_from_src);
    }
};


py::class_<Shape2d, PyShape2d, std::shared_ptr<Shape2d>>(m, "Shape2d")
    .def(py::init<const std::string &>(),
         py::arg("current_space") = "image")
    .def("GetArea", &Shape2d::GetArea);

自动监听变化

srcdir="/mnt/c/wsl_project/smore-vision/python/smorevision"
ls ${srcdir}
inotifywait -mrq  -e modify ${srcdir} \
| while read file
do
make -j8
done

vscode环境变量

            "cwd": "/mnt/c/wsl_project/smore-vision/python/unit_test/core/",    
            "python.pythonPath": "/mnt/c/wsl_project/smore-vision/python/build/smorevision/core",
            "env": {"PYTHONPATH":"/mnt/c/wsl_project/smore-vision/python/build/smorevision/core"

pybind11debug环境变量

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 启动",
            "type": "cppdbg",
            "request": "launch",
            "program": "/root/anaconda3/envs/py3/bin/python",
            "args": [
                "${file}"
            ],
            "stopAtEntry": false,
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "cwd": "/mnt/c/wsl_project/smore-vision/python/unit_test/core/",
            "python.pythonPath": "/mnt/c/wsl_project/smore-vision/python/build/smorevision/core",
            "env": {
                "PYTHONPATH": "/mnt/c/wsl_project/smore-vision/python/build/smorevision/core",
            },
        },
        {
            "name": "Python: 当前文件",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "justMyCode": true,
            "cwd": "/mnt/c/wsl_project/smore-vision/python/unit_test/core/",
            "python.pythonPath": "/mnt/c/wsl_project/smore-vision/python/build/smorevision/core",
            "env": {
                "PYTHONPATH": "/mnt/c/wsl_project/SMore-Cls/SMore-Core:/mnt/c/wsl_project/smore-vision/python/build/smorevision/core:/mnt/c/wsl_project/smore-vision/python/build/smorevision/detection"
            },
        },
        {
            "name": "PyTest",
            "type": "python",
            "request": "launch",
            "stopOnEntry": false,
            "module": "pytest",
            "args": [
                "-sv",
            ],
            "cwd": "/mnt/c/wsl_project/smore-vision/python/unit_test/core/",
            "python.pythonPath": "/mnt/c/wsl_project/smore-vision/python/build/smorevision/core",
            "debugOptions": [],
            "env": {
                "PYTHONPATH": "/mnt/c/wsl_project/smore-vision/python/build/smorevision/core"
            },
        }
    ]
}

奇奇怪怪的问题,初始化为0的mat会有杂像素,需要确保numpy类型正确

绑定exception

    static py::exception<MyException> ex9(m, "MyException");
    py::register_exception_translator([](std::exception_ptr p) {
        try
        {
            if (p)
            {
                std::rethrow_exception(p);
            }
        }
        catch (const MyException &e)

猜你喜欢

转载自blog.csdn.net/weixin_43953700/article/details/123855966