Pybind11 用于 C++ 代码,内部结构通过静态工厂方法创建

Posted

技术标签:

【中文标题】Pybind11 用于 C++ 代码,内部结构通过静态工厂方法创建【英文标题】:Pybind11 for C++ code with inner struct created via static factory method 【发布时间】:2018-01-21 22:51:01 【问题描述】:

我有自己的 C++,我正在尝试使用 Pybind11 生成 python 绑定:

auto markerParams = MarkerDetector::Params::create(MarkerType::chessboard);
markerDetector.detect(image, markerParams);

我在为MarkerDetector::Params struct 生成绑定时遇到问题,因为它是一个使用以枚举为参数的工厂方法构造的内部结构:

enum MarkerType  chessboard, tag ;

typedef std::vector<cv::Point> ContourType;
typedef std::vector<cv::Point2d> ContourTyped;

//              contour full, contour approximate, area, corners
typedef std::tuple<ContourType, ContourType, double, ContourTyped> MarkerDescriptor;


class MarkerDetector 
    public:
        std::vector<MarkerDescriptor> detect(Mat image, const Params params);

        struct Params 
            int rows, cols;
            ColorRange borderColor;
            ShapeDetector::Params borderShape;
            cv::Size borderSize;
            cv::Size Size;


            static Params create(MarkerType markerType) 
                static Params markerTypes[] = 
                     3, 6, ColorRange::GREEN, ShapeDetector::Params::RECTANGLE, cv::Size(30,30), cv::Size(140, 140) 
                ;
                return markerTypes[markerType];
            
        ;
    ;

有人知道如何处理这个更高级的案例吗?

【问题讨论】:

【参考方案1】:

我已经根据您的设计使用内部结构来运行您的代码的基本实现。为简洁起见,我只包含了 MarkerDetector 和 Params 的相关详细信息,但它应该与您所做的相匹配。

c++代码:

#include <pybind11/pybind11.h>

namespace py = pybind11;

enum MarkerType  chessboard, tag ;


class MarkerDetector 
    public:
    MarkerDetector()  
    struct Params 
        int rows;
        int cols;
        static Params create(MarkerType markerType) 
            static Params markerTypes[] = 
                     1, 2 ,
                     3, 4 
            ;
            return markerTypes[markerType];
        
    ;

;


PYBIND11_MODULE(example, m) 
    m.doc() = "pybind11 example"; // optional module docstring

    py::enum_<MarkerType>(m, "MarkerType")
         .value("chessboard", MarkerType::chessboard)
         .value("tag",        MarkerType::tag)
         .export_values();

    py::class_<MarkerDetector>(m, "MarkerDetector")
            .def(py::init<>())
            ;

    py::class_<MarkerDetector::Params>(m, "MarkerDetectorParams")
            .def(py::init<>())
            .def_readwrite("rows", &MarkerDetector::Params::rows)
            .def_readwrite("cols", &MarkerDetector::Params::cols)
            .def("create", (MarkerDetector::Params (*)(MarkerType)) &MarkerDetector::Params::create)
            ;

(如果你有兴趣,上面的命令行编译:)

c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix` -L /usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/ -lpython3.6

python代码:

import sys
sys.path.append('/Volumes/Programs/workspaces/workspace 1/Project CPP 2')

import example

mtype = example.MarkerType.chessboard
print (mtype)

x = example.MarkerDetectorParams.create(example.MarkerType.chessboard)
print (x)
print (x.rows)
print (x.cols)

y = example.MarkerDetectorParams.create(example.MarkerType.tag)
print (y)
print (y.rows)
print (y.cols)

这给出了以下输出,根据设计看起来是正确的:

MarkerType.chessboard
<example.MarkerDetectorParams object at 0x1043e35a8>
1
2
<example.MarkerDetectorParams object at 0x1043e3768>
3
4

我希望这能给你一些工作。问候,AS

【讨论】:

以上是关于Pybind11 用于 C++ 代码,内部结构通过静态工厂方法创建的主要内容,如果未能解决你的问题,请参考以下文章

使用 pybind11 通过预先存在的嵌入式 python 解释器公开 C++ 功能

在 pybind11 中引用 C++ 分配的对象

使用 pybind11 包装 C++ 抽象类时出错

python嵌入C++,函数返回shared_ptr(pybind11/boost_python)

通过使用 pybind11 的虚函数通过引用传递 std::vector 的问题

windows10系统下基于pybind11库进行c++代码调用python(pytorch)代码