我的目标是能够通过std::map<双,双>从Python到C++,用C++填充它,然后在Python端查看结果。这是如何实现的?我甚至连std::向量都无法工作。
我在C++中有一个函数定义,比如这个
void predict(std::vector<T>& seq, std::map<T, double>& probabilities)
main.cpp看起来像这个
#include "node.h"
#include "probtree.h"
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
PYBIND11_MAKE_OPAQUE(std::vector<double>);
PYBIND11_MAKE_OPAQUE(std::map<double, double>);
namespace py = pybind11;
using namespace std;
int main(int argc, char** argv){
}
PYBIND11_MODULE(sps_c, m){
py::bind_vector<std::vector<double>>(m, "VectorD");
py::bind_map<std::map<double, double>>(m, "MapDD");
py::class_<ProbTree<double>>(m, "ProbTree")
.def(py::init())
.def("process", &ProbTree<double>::process)
.def("predict", &ProbTree<double>::predict)
;
}
我所期望的一切都不起作用:
>>> import sps_c
>>> pt = sps_c.ProbTree
>>> vd = sps_c.VectorD
>>> m = sps_c.MapDD
>>> pt.process(vd)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: process(): incompatible function arguments. The following argument types are supported:
1. (self: sps_c.ProbTree, arg0: sps_c.VectorD) -> None
Invoked with: <class 'sps_c.VectorD'>
也许是名单?
>>> pt.process([1.0])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: process(): incompatible function arguments. The following argument types are supported:
1. (self: sps_c.ProbTree, arg0: sps_c.VectorD) -> None
Invoked with: [1.0]
我该如何做到这一点?
STL方法不可用也有一个问题:
vd.push_back(1.0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'sps_c.VectorD' has no attribute 'push_back'
我必须写一堆样板才能让STL容器工作吗?
您的第一个示例不起作用,因为您使用类而不是实例调用方法。我认为这应该有效:
>>> pt = sps_c.ProbTree()
>>> vd = sps_c.VectorD()
>>> pt.process(vd)
关于你的第二个例子:没有自动类型转换,所以你需要自己转换:
>>> pt_instance.process(sps_c.VectorD(vd))
关于第三个示例:push_back
和其他方法以其公共Python名称提供。这并没有很好的记录,所以这里有一个列表(从这里(:
bind_vector
公开了append
、clear
、extend
、insert
、pop
和一些迭代器方法。bind_map
公开了keys
、values
、items
和一些迭代器方法。
如果包含的类型不可复制,则这些方法可能不可用。