使用 C++ 指针调用 python 函数
Posted
技术标签:
【中文标题】使用 C++ 指针调用 python 函数【英文标题】:Call python function with C++ pointers 【发布时间】:2020-06-15 19:33:17 【问题描述】:我想将一个可调用对象从 Python 传递到 C++,然后从 C++ 调用它,并使用我已注册的参数 base_
。示例:
namespace bpy = boost::python;
bpy::class_<X, X*, boost::noncopyable>("X", bpy::no_init);
bpy::def("f", +[](bpy::object fn)
fn(new X());
);
然后从python:
from example import f
def fn(x):
print "x.g() =", x.g()
f(fn)
投掷:
TypeError: No to_python (by-value) converter found for C++ type: X
我对 callable 采用其他类型的参数没有任何问题,例如,int
、float
或我注册的其他类型,但是这个失败了,我不明白为什么:为什么是 by-当我传递 X*
并且我指定 X
的持有类型为 X*
时,需要进行值转换。
关于如何解决此问题的任何建议?
关于 Coliru 的完整示例:http://coliru.stacked-crooked.com/a/b3492d2e846d705c
【问题讨论】:
【参考方案1】:根据Argument Handling in Calling Python Functions and Methods:
参数根据其类型转换为 Python。默认情况下, 参数 a1...aN 被复制到新的 Python 对象中,但这 使用 ptr() 和 ref() 可以覆盖行为:
类 X : boost::noncopyable ... ;
void apply(PyObject* callable, X& x) // 调用 callable,传递 一个 Python 对象,其中包含对 x 的引用 boost::python::call(callable, boost::ref(x));
似乎即使指定了指针类型,实现也采用了基本的非指针类型。但在这种情况下,boost::ref
或 bpy::ptr
无论如何都可以用来解决问题。
变化:
bpy::def("f", +[](bpy::object fn)
fn(new X());
);
进入:
bpy::def("f", +[](bpy::object fn)
return fn(bpy::ptr(new X()));
);
现在它可以工作了:
$ python test.py
x.g() = 0
【讨论】:
谢谢,这是我在发布问题后立即找到的解决方案。问题是在我的用例中,这些是模板化的东西,所以我必须根据参数应用bpy::ptr
(或boost::ref
),但并非所有指针/引用参数都应该被包装,这会造成相当混乱最后......我想知道这种奇怪行为背后的原因,因为对于使用bpy::def
或bpy::class_::def
定义的python 函数,参数会自动正确包装,并且从包装器调用get_override
时也是如此。以上是关于使用 C++ 指针调用 python 函数的主要内容,如果未能解决你的问题,请参考以下文章