修改传递给 C 函数的 Python 变量

Modifying Python variable passed to C function

我正在导入一个用 C 编写的共享对象库,并调用我使用 Python.h 库实现的一些包装函数。

我有一个具有以下原型的函数:

PyObject *Cal_readFile( PyObject *self, PyObject *args );

我解析出以下元组:

PyArg_ParseTuple(args, "sO", &filename, &result)

来自 python 的呼叫如下所示:

result = []
status = Cal.readFile(filename, result)
print(result)

调用正常,函数肯定运行。我的目标是在调用的 C 函数中修改 result 变量。而这正是我所做的。我修改了 C 函数中的结果变量,并使用 result = Py_BuildValue("[lO]", (long)comp, compList); 将新数据放入其中。

然而,当我 print 结果为 Python 时,我仍然有与开始时相同的空列表。

是否需要执行一些额外的步骤来从 C 函数修改此 python 变量?我不能在 return 中使用它,因为你已经看到我正在从那里收集 return 状态(这个 return 有效)。

编辑:来自 readCal 的一些可能有用的代码:

PyObject *result = NULL;
PyArg_ParseTuple(args, "sO", &filename, &result);
//Some creating of data is done, and then I am trying to set the list to that data:

result = Py_BuildValue("[lO]", (long)comp, compList);

当你这样做时:

PyArg_ParseTuple(args, "sO", &filename, &result)

您正在将 python 处理的实例引用分配给 result 指针。

然后当你这样做时:

result = Py_BuildValue("[lO]", (long)comp, compList);

您正在替换结果指针所引用的值。这意味着在您的 python 代码中,result 变量仍然指向前一个实例。

如果要修改指向的列表实例,则应使用 C 中的 List 方法来改变实例本身,而不是创建新实例。

基本上,您在 C 代码中所做的与以下 python 代码相同:

>>> def foo(result):
...    result = [4,5,6]
...
>>> result = [1,2,3]
>>> foo(result)
>>> print(result)
[1,2,3]

您想要做的是 — 在 python — 是:

>>> def foo(result):
...    while len(result): 
...        result.pop() # or any operation that mutates the result instance
...    result += [4,5,6]
...
>>> result = [1,2,3]
>>> foo(result)
>>> print(result)
[4,5,6]

现在我留给你使用 C API ;-)

HTH

您不能完全替换 result,但可以向其 append 值,或删除现有值等。像这样的东西可以满足您的需要:

if (!PyArg_ParseTuple(args, "sO", &filename, &result)) {
    return NULL;
}

PyObject *l = PyLong_FromLong((long)comp);
if (!l) {
    return NULL;
}

int success = PyList_Append(result, l);
Py_DECREF(l);
if (! success) {
    return NULL;
}

success = PyList_Append(result, complist);
if (! success) {
    return NULL;
}