我通过boost python封装了模板类A和B,并尝试在它们之间进行转换。为了实现这一点,我实现了toB函数并用return_internal_reference<>包装了它。但是,它不返回python中的B对象,而是返回“已死”的A对象,其中的成员函数不能再使用。
我缩小了问题的范围,它是基类Bar中的虚函数。如果我删除了hi()的虚拟关键字,toB函数会正确地返回引用到A对象的B对象。但是,正确的方法是什么呢?为什么基类中的虚函数会影响结果?另一方面,有没有一种方法可以直接在Python中转换boost python包装类?
#include <boost/python.hpp>
#include <iostream>
using namespace boost::python;
struct Bar
{
virtual void hi() { std::cout << "Hi Bar." << std::endl; }
virtual ~Bar() {}
};
template<typename T>
struct Foo : Bar
{
void set(T v) { val = v; }
T get() { return val; }
private:
T val;
};
using A = Foo<unsigned short>;
using B = Foo<short>;
B & toB(A & a) { return *reinterpret_cast<B*>(&a);}
BOOST_PYTHON_MODULE(example)
{
class_<A>("A")
.def("set", &A::set)
.def("get", &A::get)
;
class_<B>("B")
.def("set", &B::set)
.def("get", &B::get)
;
def("toB", &toB, return_internal_reference<>());
}Python执行
>>> from example import *
>>> a = A()
>>> toB(a)
<example.A object at 0x7f7139cd27c0>
>>> toB(a).get()
Traceback (most recent call last):
File "<stdin>", line 1 in <module>
Boost.Python.ArgumentError: Python argument types in
A.get(A)
did not match C++ signature:
get(Foo<unsigned int> {lvalue})如果我在Bar中删除了虚拟关键字,它会工作得很好。
struct Bar
{
void hi() { std::cout << "Hi Bar." << std::endl; }
};>>> from example import *
>>> a = A()
>>> toB(a)
<example.B object at 0x7f511000c7c0>
>>> toB(a).get()
>>> 4.484155085839415e-44发布于 2018-11-08 19:01:41
公开的类A和B没有向python提供关于其结构的所有必要信息。具体地说,它们是从类Bar派生的。为了解决这个问题,还要向python公开类Bar,并通知Boost.Python Bar和A之间以及Bar和B之间的继承关系
BOOST_PYTHON_MODULE(example)
{
class_<Bar>("Bar")
.def("hi", &Bar::hi)
;
class_<A, bases<Bar>>("A")
.def("set", &A::set)
.def("get", &A::get)
;
class_<B, bases<Bar>>("B")
.def("set", &B::set)
.def("get", &B::get)
;
def("toB", &toB, return_internal_reference<>());
}在此之后,一切都应该按预期工作:
>>> from example import *
>>> a=A()
>>> b=toB(a)
>>> b.get()
0https://stackoverflow.com/questions/53174370
复制相似问题