从C++调用Python函数

18

我试图实现从C++调用Python函数。我认为可以通过函数指针来实现,但似乎不可能。我一直在使用boost.python来实现这一点。

假设有一个在Python中定义的函数:

def callback(arg1, arg2):
    #do something
    return something

现在我需要将这个函数传递给C++,以便可以从那里调用它。我该如何使用boost.python编写C ++端的代码来实现这一点?

4个回答

15

如果它可能有任何名称:

将其传递给一个接受 boost::python::object 的函数。

bp::object pycb; //global variable. could also store it in a map, etc
void register_callback(bp::object cb)
{
      pycb = cb;
}

如果它在单个已知名称空间中并具有一致的名称:

bp::object pycb = bp::scope("namespace").attr("callback");

bp::object拥有定义的operator(),因此您可以像调用任何函数一样调用它。

ret = pycb()

谢谢Matthew,我有一个额外的问题。这里Python对象是从同一线程中调用的。如果Python对象是全局的,并且从不同的线程中调用呢? - Amar
这是可能的,虽然有点超出了本问题的范围。我建议研究C/Python API的PyGILState_*函数族。与Boost-Python不同,Python有非常好的文档。如果您仍需要更多帮助,请提出另一个问题。 - Matthew Scouten
2
给未来的观众:最终有人提出了另一个问题,我已经回答了。请看这里:stackoverflow.com/questions/8009613/boost-python-not-supporting-parallelism/8011153#8011153 - Matthew Scouten
1
@MatthewScouten,您能否提供一个简单的工作示例来帮助我更好地理解上述主题?因为我很新手C++,而且我更了解Python。 - lkkkk
谢谢。现在如果Boost文档中能够给出一个简单的示例,说明如何做到这一点就好了... 至少我们还有Stack Overflow。 - CashCow

4
没有头绪。但是一旦你有函数对象,你可以使用PyObject_Call()来调用它。

2
如果你有一个 boost::python::object,你可以直接使用它的 operator() 来调用它。 - eudoxos

2

我之前没有使用过这个,但是参考手册中有一个章节叫做调用Python函数和方法,似乎展示了如何实现这一功能。


2
Boost Python的文档大部分已经过时,即使是最新的部分也非常糟糕。 - Matthew Scouten
那个页面并没有展示一个Python函数,它只是展示了如何使用已绑定对象来调用函数。并不算是一个“简单的例子”。 - CashCow

1

我使用了PyRun_SimpleString("myFunction()")作为快速解决方案,因为我的函数名称已知,不需要参数,并且位于__main__命名空间中。请注意,如果您是多线程的,则还需要获取锁GIL。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接