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

时间:2016-03-18 18:52:48

标签: python c shared-objects

我正在导入一个用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中使用它,因为您已经看到我从那里收集返回状态(此返回有效)。

编辑:来自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);

2 个答案:

答案 0 :(得分:2)

您无法完全替换class TestMainFunction(unittest.TestCase): def setUp(self): self.mock = MagicMock(wraps=CallerMock()) self.main_class = MainClass(self.mock) def test(self): # self.main_class.caller.items = items # self.mock.items = items # self.mock.function2.return_value = items self.main_class.some_functions() # non of the above change the return value of function2 ,但可以result为其值,或删除现有值等等。这样的事情可以做你需要的事情:

append

答案 1 :(得分: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