【问题标题】:Boost.Python call by reference : TypeError: No to_python (by-value) converter found for C++ type:Boost.Python 引用调用:TypeError: No to_python (by-value) converter found for C++ type:
【发布时间】:2011-07-17 06:06:52
【问题描述】:

我正在尝试使用 Boost.Python 将我的 C++ 类公开给 Python。这是我正在尝试做的简单版本:

我有一个从 boost::noncopyable 派生的 A 类和第二个 B 类,其方法将 A 的引用作为参数。

class A : boost::noncopyable { /*...*/ };

class B {

public:

    virtual void do_something(A& a) {
        /*...*/
    }
};

我将这些类公开如下:

/* Wrapper for B, so B can be extended in python */
struct BWrap : public B, wrapper<B> {

    void do_something(A &a) {

        if (override do_something = this->get_override("do_something")) {
            do_something(a);
            return;
        }
        else {
            B::do_something(a);
        }
    }

    void default_do_something(A& a) { this->B::do_something(a); }
};

BOOST_PYTHON_MODULE(SomeModule) {

    class_<A, boost::noncopyable>("A");

    class_<BWrap, boost::noncopyable>("B")
        .def("do_something", &B::do_something, &BWrap::default_do_something)
    ;
}

我像这样在python中扩展B:

test.py:

import SomeModule


class BDerived(SomeModule.B):

    def do_something(self, a):
        pass

并像这样调用扩展的 B:

try {
    py::object main = py::import("__main__"); \
    py::object global(main.attr("__dict__")); \
    py::object result = py::exec_file("test.py", global, global); \
    py::object pluginClass = global["BDerived"]; \
    py::object plugin_base = pluginClass(); \

    B& plugin = py::extract<B&>(plugin_base) BOOST_EXTRACT_WORKAROUND;

    A a;
    B.do_something(a);
}
catch (py::error_already_set) { 
    PyErr_Print();
}

但是这会导致错误消息:

TypeError: No to_python (by-value) converter found for C++ type: A

如果A 不是从boost::noncopyable 派生的,则代码运行时不会出现任何错误,但do_something(A&amp; a) 中的参数a 在函数调用期间会被复制,即使它是通过引用传入的。但是仅仅删除A 上的不可复制要求并不是一种选择,因为它的存在是有原因的。

有什么解决问题的建议吗?

谢谢。

【问题讨论】:

  • 对于登陆这里的人:Boost 1.60.0 中最近有一个看起来很像这样的错误,应该在 Boost 1.61.0 中修复,另见github.com/boostorg/python/pull/59
  • @KennethHoste 非常感谢!你让我免于几天甚至几周的错误!很高兴我发现了这个小评论!! :)

标签: c++ python boost boost-python


【解决方案1】:

B.do_something(a); 更改为B.do_something(boost::ref(a));

请参阅 boost 手册中的Calling Python Functions and Methods

【讨论】:

  • 非常感谢!你给了我正确的提示。即使我必须在包装类 BWrap do_something(boost::ref(a)); 中更改它,而不是在调用 B.do_something(a); 时更改它。令人难以置信的是,即使是几个小时的谷歌搜索也没有给我这个提示。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-09
  • 2020-04-16
  • 1970-01-01
  • 2019-02-20
  • 2013-11-10
相关资源
最近更新 更多