Boost.Python 通过引用调用:类型错误:找不到 C++ 的 to_python (by-value) 转换器类型:
我正在尝试使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
将
B.do_something(a);
更改为B.do_something(boost::ref(a));
。请参阅调用 Python 函数和方法 在升压手册中。
Change
B.do_something(a);
toB.do_something(boost::ref(a));
.See Calling Python Functions and Methods in the boost manual.