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++ 功能
python嵌入C++,函数返回shared_ptr(pybind11/boost_python)