Boost.Python 通过引用调用:类型错误:找不到 C++ 的 to_python (by-value) 转换器类型:

发布于 2024-10-23 01:26:28 字数 1977 浏览 1 评论 0原文

我正在尝试使用 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

If A isn't generated从 boost::noncopyable 开始,代码运行时没有任何错误,但是 do_something(A& a) 中的参数 a 在函数调用期间被复制,即使它是通过引用传入的。但仅仅删除 A 上的不可复制要求并不是一个选择,因为它的存在是有原因的。

有什么建议如何解决问题吗?

谢谢。

I'm trying to expose my C++ Classes to Python using Boost.Python. Here is a simplyfied version of what i'm trying to do:

I have a class A deriving from boost::noncopyable and a second class B with a method that takes a reference to A as an argument.

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

class B {

public:

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

I'm exposing the classes as follows:

/* 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)
    ;
}

I extend B in python like this:

test.py:

import SomeModule


class BDerived(SomeModule.B):

    def do_something(self, a):
        pass

and call the extended B like this:

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();
}

However this results in an error message:

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

If A isn't derived from boost::noncopyable the code runs without any errors but the argument a in do_something(A& a) gets copied during the function call even though it's passed in by reference. But just removing the noncopyable requirement on A isn't an option since it's there for a reason.

Any suggestions how to solve the problem?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

×纯※雪 2024-10-30 01:26:28

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

请参阅调用 Python 函数和方法 在升压手册中。

Change B.do_something(a); to B.do_something(boost::ref(a));.

See Calling Python Functions and Methods in the boost manual.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文