在boost :: python中更改纯虚拟函数的签名

时间:2019-04-07 19:58:00

标签: python c++ windows boost-python

我有一个C ++层次结构,需要在python中进行镜像。基类由几个静态函数,多个纯虚拟函数和多个具有默认实现的简单公共函数组成。这些方法中的许多都可能使用非常量引用来返回参数列表中的值。以pythonic方式实现这一点,我想返回与元组相同的值。这可能吗?

此问题与未解决的问题非常相似 Boost python wrapping a virtual method,除了所讨论的函数是纯虚函数外,并且同时更改参数和返回值。

class Driver_comm
{
public:

   Driver_comm() {};
   virtual ~Driver_comm() {};

   // -------------------------------------------------------------------------
   virtual bool Enumerate_devices(const uint32_t vendor_id,
      uint32_t &n_devices,
      std::string &details) = 0;
};

class Driver_sim : public Driver_comm
{
public:
   Driver_sim() {}
   ~Driver_sim() {}

   // -------------------------------------------------------------------------
   Driver_sim(const Driver_sim& r) = delete;

   // -------------------------------------------------------------------------
   const Driver_sim& operator=(const Driver_sim& r) = delete;

   // -------------------------------------------------------------------------
   bool Enumerate_devices(const uint32_t,
      uint32_t &n_devices,
      std::string &) override {
      n_devices = 1; return true;
   }
};

// ============================================================================

using namespace boost::python;

BOOST_PYTHON_MODULE(example)
{
   struct Comm_wrapper : public Driver_comm, public wrapper<Driver_comm>
   {
      tuple enumerate_devices(const uint32_t vendor_id)
      {
         uint32_t n_devices;
         std::string details;
         bool ok = false;
         override f_enumerate = this->get_override("Enumerate_devices");
         if (f_enumerate)
         {
            ok = f_enumerate(vendor_id, n_devices, details);
         }
         else
         {
            printf("override = None");
         }
         return make_tuple(ok, n_devices, details.c_str());
      }
   };

   class_<Comm_wrapper, boost::noncopyable>("driver_comm", no_init)
      .def("Enumerate_devices", (&Comm_wrapper::enumerate_devices))
      ;

   class_<Driver_sim, boost::noncopyable, bases<Driver_comm> >("driver_sim", init<>())
      ;
}

致电

    n_devices = 0
    result = ""
    ok, n_devices, result = d.Enumerate_devices(0x1010)

导致“未匹配C ++签名”错误。

    Python argument types in driver_comm.Enumerate_devices(driver_sim, int)
did not match C++ signature:
    Enumerate_devices(struct `void __cdecl init_module_example(void)'::`2'::Comm
_wrapper {lvalue}, unsigned int)

由于功能类型不匹配,https://www.boost.org/doc/libs/1_43_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.virtual_functions_with_default_implementations中建议的向包装器添加默认实现无法构建:

error C2664: 'void boost::python::detail::error::not_a_derived_class_member<Default>(Default)' : cannot convert argument 1 from 'bool (__cdecl Driver_comm::* )(uint32_t,uint32_t &,std::string &)' to 'boost::python::tuple (__cdecl init_module_example::Comm_wrapper::* )(uint32_t)'

任何解释都值得赞赏。如果pybind11(或其他工具)有更好的方法来解决此问题,我将很乐意为您解决。

0 个答案:

没有答案