【发布时间】:2021-06-16 07:34:14
【问题描述】:
我在传回 <:vector detection>>> 时遇到问题,我希望有人能帮助我。我能够传递向量的向量,但是当我尝试访问 Detection 时,我得到一个 TypeError,表明没有为模块定义中的 C++ 类 boost::shared_ptr 注册 python 类。
我的C++代码如下:
class Detection {
public:
Detection () {};
~Detection() {};
double getR () {return r_;};
double getA () {return a_;};
double r_;
double a_;
}
class Detector {
public
std::vector <std::vector <boost::shared_ptr <Detection> > > getDetections();
}
std::vector <std::vector <boost::shared_ptr <Detection> > >
Detector::getDetections () {
std::vector <std::vector <boost::shared_ptr <Detection> > > allVecDetections;
// Build 4 vectors containing 2 detections each
for (unsigned int i=0; i < 4; i++) {
std::vector<boost::shared_ptr<Detection> > vecDetections;
for (unsigned int j = 0; j < 2; j++ ) {
boost::shared_ptr<Detection> dt (new Detection (j+i, ts));
dt->r_ = (j+i) + (j*i);
dt->a_ = (j+i) * (j*i);
vecDetections.push_back (dt);
}
allVecDetections.push_back (vecDetections);
}
return allVecDetections;
}
// Module.cpp
BOOST_PYTHON_MODULE (myModule) {
boost::python::class_<Detector>("Detector")
.def("getDetections", &getDetections)
;
boost::python::class_<Detection>("Detection")
.def("getA", &getA)
.def("getR", &getR)
;
// Map list of Detections
boost::python::class_<std::vector <boost::shared_ptr <Detection> > > ("DetectionVector")
.def(vector_indexing_suite<std::vector <boost::shared_ptr <Detection> > > ());
// Map list of lists of Detections
boost::python::class_<std::vector <std::vector <boost::shared_ptr <Detection> > > > ("DetectionVectorVector")
.def(vector_indexing_suite<std::vector<std::vector <boost::shared_ptr <Detection> > > > ());
// Register our shared pointers with Python
register_ptr_to_python<boost::shared_ptr<Detection> >();
}
我可以从 Python 调用 getDetections 并返回 4 个向量,每个向量包含 2 个检测。这是 Python 代码:
import myModule
...
plots = det.getDetections()
numvectors = len(plots)
print (f'Received {numvectors} vectors ')
jdx = 0
pdx = 0
while jdx < numvectors:
detections = plots[jdx]
pdx = 0
numPlots = len(detections)
print (f'Received {numPlots} extractions')
while pdx < numPlots:
print ("Extraction " + str (pdx) + ":")
detect = detections[jdx]
这会运行,但我得到以下输出:
Received 4 vectors
Received 2 extractions
Extraction 0:
Traceback (most recent call last):
File "scripts/test.py", line 87, in <module>
foo = detections[jdx].getA()
TypeError: No Python class registered for C++ class boost::shared_ptr<Detection>
那么,为什么我会抱怨 Python 没有为 boost::shared_ptr 注册的类?
感谢您能给我的任何帮助。 (上面的代码已经被修剪,所以在写问题的过程中可能引入了拼写错误)。
接受 Valeca 的建议,我重新完成了传回 vector
以下是新变化:
class Detection {
public:
Detection () {};
~Detection() {};
Detection (const Detection &D) {
: r_ (D.r_),
a_ (D.a_)
{};
void operator = (const Detection &D) {
r_ = D.r_;
a_ = D.a_;
};
double getR () {return r_;};
double getA () {return a_;};
double r_;
double a_;
friend bool operator== (const Detection &d1, const Detection &d2);
friend bool operator!= (const Detection &d1, const Detection &d2);
};
bool operator== (const Detection &d1, const Detection &d2) {
return (d1.r_ == d2.r_ && d1.a_ == d2.a_);
}
bool operator!= (const Detection &d1, const Detection &d2) {
return !(d1.r_ == d2.r_ && d1.a_ == d2.a_ );
}
class Detector {
public
std::vector <std::vector <Detection> > getDetections();
}
std::vector <std::vector <Detection> >
Detector::getDetections () {
std::vector <std::vector <Detection> > allVecDetections;
// Build 4 vectors containing 2 detections each
for (unsigned int i=0; i < 4; i++) {
std::vector<Detection> vecDetections;
for (unsigned int j = 0; j < 2; j++ ) {
Detection dt (j+i, ts);
dt.r_ = (j+i) + (j*i);
dt.a_ = (j+i) * (j*i);
vecDetections.push_back (dt);
}
allVecDetections.push_back (vecDetections);
}
return allVecDetections;
}
// Module.cpp
BOOST_PYTHON_MODULE (myModule) {
boost::python::class_<Detector>("Detector")
.def("getDetections", &getDetections)
;
boost::python::class_<Detection>("Detection")
.def("getA", &getA)
.def("getR", &getR)
;
// Map list of Detections
boost::python::class_<std::vector <Detection> > ("DetectionVector")
.def(vector_indexing_suite<std::vector <Detection> > ());
// Map list of lists of Detections
boost::python::class_<std::vector <std::vector<Detection> > > ("DetectionVectorVector")
.def(vector_indexing_suite<std::vector<std::vector <Detection> > > ());
// Register our shared pointers with Python
// register_ptr_to_python<boost::shared_ptr<Detection> >();
}
现在 Python 端 seg 在启动时出现错误。我可能添加了比需要更多的重载运算符,但没有它们,我会看到:
*/usr/include/c++/7/bits/predefined_ops.h:241:17:错误:'operator==' 不匹配(操作数类型为'Detection'和'const Detection ') { 返回 __it == _M_value; }
在编译我的模块时。
感谢您对此提供的任何启发。
【问题讨论】:
-
我看不出使用共享指针的原因。你能解释一下你为什么使用它们吗?您是否尝试将向量定义为 std::vector
vecDetections 并推回对象?最好避免使用向量作为向量本身的项。 -
根据您的建议,我也尝试了它 vector
> 这还需要在 Detection 类上实现 ==, != = 运算符(在编译时在 Module. cpp 没有它)。当我现在运行时,我在加载模块之前出现了段错误,这通常意味着 Python 不知道如何实例化我的向量。所以我必须遗漏一些必需的重载方法,以便 Python 知道收到后要做什么。这就是我开始使用 shared_ptr 的原因之一。 -
在某种程度上与您最初使用 shared_ptr stackoverflow.com/questions/5055443/… 遇到的问题类似。
-
我想是的。我能够使用 boost::shared_ptr 将对象从 C++ 传递回 Python,并让它按预期工作。我还可以传回一个 vector
>> 并按预期工作。我不确定为什么 boost::shared_ptr 或检测类有问题 - 我唯一能想到的是我在模块定义中缺少一个 kep 映射。
标签: python c++ vector shared-ptr boost-python