从C ++使用任意数量(编译时未知)的参数调用Python函数

时间:2019-07-18 19:18:59

标签: python c++

我需要从C ++调用以下形式的Python函数

def function(a, b, *c)
    print(a) # Mock example
    print(b) # Mock example
    print(c) # Mock example

要求:我不应该修改Python函数。它们由用户提供,并且应具有该签名以保持一致性。

Python.h界面provides(通过链接引用,以使您不必打开其他页面):

  1. PyObject* PyObject_CallFunction(PyObject *callable, const char *format, ...) 返回值:新参考。 调用可调用的Python对象,该对象具有可变数量的C参数。使用Py_BuildValue()样式格式字符串描述C参数。格式可以为NULL,表示未提供任何参数。 成功时返回调用结果,或者引发异常,失败时返回NULL。 这等效于Python表达式:callable(* args)。 请注意,如果仅传递PyObject * args,则PyObject_CallFunctionObjArgs()是更快的选择。

  2. PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ..., NULL) 返回值:新参考。 调用可调用的Python对象,该对象具有可变数量的PyObject *参数。提供的参数是可变数量的参数,后跟NULL。 成功时返回调用结果,或者引发异常,失败时返回NULL。 这等效于Python表达式:callable(arg1,arg2,...)

在编译时未知作为c的一部分传递的参数的数量。在运行时,我将它们作为指向元组的PyObject *(我们称之为cc)。假设a的输入为PyObject *的{​​{1}},ca的输入为cbb的输入为{ {1}}引用了PyObject *

我怎么打这个电话?

我尝试过:

  1. cfunction,并且与传递function字符串的其他方法类似。但这似乎导致在Python中调用PyObject_CallFunctionObjArgs(cfunction, ca, cb, cc)形式。在Python代码内部,format不是一个我在function(a, b, (c,))中具有的值的元组,而是一个1元素元组,第一个条目是我在{{1}中具有的元素的元组}。

  2. 我还尝试创建一个新的c cc,特别是一个cc,其中包含PyObject *cd的内容作为前两个元素其余元素为PyTupleObject的元素。然后,我打了一个ca之类的电话。但是这次Python抱怨cb需要位置参数cc。我认为是因为PyObject_CallFunctionObjArgs(cfunction, cd)中的元组已完全分配给function

2 个答案:

答案 0 :(得分:0)

您快到了:将cd元组传递给PyObject_CallObject

答案 1 :(得分:0)

以下工作有效:

$user = new App\User;
$user->username = 'xyz';
$user->save();

它等效于Python中的调用

PyObject_CallFunctionObjArgs(cfunction, ca, cb, cc, NULL)