【问题标题】:boost-python pure virtual detecting missing implementationboost-python 纯虚拟检测缺失的实现
【发布时间】:2019-07-01 22:17:30
【问题描述】:

我有一个 C++ 类,它有一个使用 boost-python 暴露给 python 的纯虚方法。我从 C++ 调用虚函数并假设虚函数是在 python 中实现的。如果实现了该功能,这一切都可以工作,但如果没有实现,我会得到一个讨厌的异常。

我正在尝试找到一种方法来检测该方法是否实际上在我加载类时无需调用即可实现

代码大概是这样的

#include <boost/python.hpp>

using namespace boost::python;

public Foo {
public:
   void func() = 0;
}

class PyFoo : public Foo, public boost::python::wrapper<Foo> {
public:
    void func() override {
        get_override("func")();
    }
};

BOOST_PYTHON_MODULE(example)
{
    using namespace boost::python;
    class_<PyFoo>, boost::noncopyable>("Foo")
        .def("func", pure_virtual(&PyFoo::func))
        ;
}

void create {
    object main_module = import("__main__");
    object main_namespace = main_module.attr("__dict__");

    std::string overrideCommand(
    R"(
    import example

    class MyFoo(example.Foo):
        def __init__(self):
            example.Foo.__init__(self)

    # virtual function in C++. (Should be defined)
    #    def func(self):
    #        print('func called')
    )");

    boost::python::exec(overrideCommand.c_str(), main_namespace);
    result = eval("MyFoo()", main_namespace);

    // Can I detect if 'result' has func implemented? If I call it and it
    // is not defined death results. I have tried:
    object attr = result.attr("func");

    // but attr always seems to be set even if there is no function,
    // I think from the base class Foo.

    // This is the call:
    Foo& t = extract<Foo&>(result);
    t.func();
}

【问题讨论】:

    标签: c++ boost-python pure-virtual


    【解决方案1】:

    您可以使用PyCallable_Check

    if (!PyCallable_Check(result.func()))
    {
        PyErr_SetString(PyExc_TypeError, error_msg.str().c_str());
        python::throw_error_already_set();
    }
    

    【讨论】:

    • 我无法让它完全编译,所以我尝试了各种版本,但它总是说它是可调用的,即使调用崩溃了。我认为基类正在定义一个它认为是可调用的存根 'PyObject *callback = PyObject_GetAttrString(result.ptr(), "func"); if (!PyCallable_Check(callback))'
    【解决方案2】:

    我找到了解决方案。实用不优雅。我添加了方法:

    bool isThere()  {
        auto obj = get_override("func");
        return PyCallable_Check(obj.ptr());
    }
    

    到 FooPy。那么:

    FooPy& t = extract<FooPy&>(result);
    t.isThere();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-10
      • 1970-01-01
      • 2012-05-04
      • 2012-11-13
      • 2011-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多