提升Python返回引用以进行虚拟函数的投入参数的转换工作不正常

2024-09-29 06:27:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我通过boostpython包装模板类A和B,并尝试在它们之间转换。我实现了toB函数,并用return\u internal\u reference<;>将其包装起来以实现这一点。但是,它在python中不返回B对象,而是返回“死”的A对象,其中的成员函数不能再使用了。

我缩小了问题的范围,即基类Bar中的虚函数。如果我删除hi()的virtual关键字,toB函数将正确返回引用到对象的B对象。但是,正确的方法是什么?为什么基类中的虚函数会影响结果?另一方面,有没有一种方法可以直接在python中强制转换boostpython包装类?你知道吗

#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

Tags: 对象函数getreturnfooexampledefvirtual
1条回答
网友
1楼 · 发布于 2024-09-29 06:27:32

公开的类AB没有向python提供有关其结构的所有必要信息。特别是它们派生自类Bar。 为了解决这个问题,还将类Bar暴露给python并通知Boost.Python版本关于BarA之间以及BarB之间的继承关系:

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()
0

相关问题 更多 >