修改传递给 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;
}
我正在导入一个用 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;
}