2016-03-18 32 views
2

我正在导入用C编写的共享对象库,并调用一些使用Python.h库进行工作的包装函数。修改传递给C函数的Python变量

我有如下原型的函数:

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

我分析出下列元组:

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

从蟒蛇的调用如下:

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

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

但是,当我然后print结果在Python中,我仍然有我开始的空列表。

是否需要执行一些额外的步骤来从C函数修改此python变量?我不能在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); 
+0

你的意思是你想追加**这些值的Python列表?你不能在Python中替换**这样的变量,在C中也不可能。 –

+0

并且请为'Cal_readFile'提供更多代码 –

+0

@AnttiHaapala是的,我认为追加可能是正确的方法。该文件相当大,这就是为什么我不粘贴它。我会编辑一些可能相关的部分。 – ComputerLocus

回答

2

不能代替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; 
} 
+0

或者可以使用'PyList_SetSlice'一个元组,如果第二个附加失败,则仍然有1个项目附加到列表 –

+0

好的建议,但是如果它没有得到一个,那么很可能两个都失败了。第一个实际上只是存储C指针,第二个部分是来自该指针地址的一些操纵数据。 – ComputerLocus

1

当你这样做:

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