我有一个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(或其他工具)有更好的方法来解决此问题,我将很乐意为您解决。