使用 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 采用其他类型的参数没有任何问题,例如,intfloat 或我注册的其他类型,但是这个失败了,我不明白为什么:为什么是 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::refbpy::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::defbpy::class_::def 定义的python 函数,参数会自动正确包装,并且从包装器调用get_override 时也是如此。

以上是关于使用 C++ 指针调用 python 函数的主要内容,如果未能解决你的问题,请参考以下文章

带有指针参数的 C++ 函数

使用指针调用 C++ DLL 函数

c#调用c++的DLL,接口函数参数有函数指针,在线等解决办法

使用 ctypes 调用带有指针参数的 C++ 函数

c++指针函数的使用——回调函数

c++的函数指针是怎么用的呀?