问题描述
我正在尝试使用 Boost.Python 将我的 C++ 类公开给 Python.这是我正在尝试做的事情的简化版本:
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:
我有一个从 boost::noncopyable 派生的类 A 和第二个类 B,其方法将 A 的引用作为参数.
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) {
/*...*/
}
};
我公开的类如下:
/* 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 是这样的:
I extend B in python like this:
test.py:
import SomeModule
class BDerived(SomeModule.B):
def do_something(self, a):
pass
并像这样调用扩展的 B:
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
如果 A
不是从 boost::noncopyable
派生的,则代码运行没有任何错误,但是 do_something(A& a)
中的参数 acode> 在函数调用期间被复制,即使它是通过引用传入的.但是仅仅删除 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?
谢谢.
推荐答案
将 B.do_something(a);
更改为 B.do_something(boost::ref(a));代码>.
参见 调用 Python 函数和方法 在 boost 手册中.
See Calling Python Functions and Methods in the boost manual.
这篇关于Boost.Python call by reference:TypeError: No to_python (by-value) converter found for C++ type:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!