我有一个包含以下功能的设备的C库:
int GetDevInfo(int *devices);
在这种情况下,devices是一个整数数组,可能已经定义如下:
int devices[10]
该函数将循环通过硬件总线以查找活动设备。在找到它们时,它会将设备编号放入devices[]
中的下一个可用位置。例如,在扫描之前:
devices = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
和全局变量DeviceCount
知道有0个活动变量。该功能发挥其神奇作用,并决定设备5和8是否有效。那么:
devices = {5, 8, 0, 0, 0, 0, 0, 0, 0, 0}
和DeviceCount
知道有2个。
我希望Python函数类似于:
devices = list(range(64))
for i in range(0,len(devices)): # Set them all to 0
devices[i] = 0
DeviceCount = 0
# Now we'll update it
DeviceCount = myModule.GetDevInfo(DeviceCount, devices)
返回时,DeviceCount
可能设置为2,设备如下:
[5, 8, 0, 0, 0, 0, 0, 0, 0, 0]
我已经为其他包装器编写代码,这些包装器传入整数并传回字符串,但我找不到任何网络智慧来帮助我解决这个问题。我知道如果我做这样的事情:
def f(a, data):
a.append(data)
l = [1, 2, 3]
f(l, 4)
我得到l=[1, 2, 3, 4]
但是如何使用Python包装器获得该效果并不明显。
提前谢天谢地,对于任何可以提供帮助的人来说都有披萨钱!
答案 0 :(得分:0)
好的,稍后阅读网页和大量的反复试验......
static PyObject* LMS_module_timesTwo(PyObject *self, PyObject *args)
{
int i, numLines;
PyObject *listObj, *numObj;
unsigned int n;
n = PyTuple_Size(args);
if (1 == n) {
/* argument 1 should be an list of integers */
listObj = PyTuple_GetItem(args, 0);
/* get the number of elements in the list */
numLines = PyList_Size(listObj);
/* should raise an error here. */
if (numLines < 0) return NULL; /* Not a list */
for (i=0; i<numLines; i++) {
numObj = PyList_GetItem(listObj, i);
n = PyLong_AsUnsignedLong(PyNumber_Long(numObj));
// This is the action - multiply by 2 for the test case
n = n * 2;
PyList_SetItem(listObj, i, Py_BuildValue("i", n));
}
} else {
PyErr_SetString(PyExc_ValueError, "Function expects one argument");
return NULL;
}
return PyLong_FromLong(1);
}
使用该代码作为扩展的一部分(我遗漏了其他结构位,但如果有人需要它可以发布整个事情),这作为Python 3测试程序,它工作膨胀!
import my_module
testlist = [1, 2, 3, 4, 5]
print("List before multiplying = ",testlist)
my_module.timesTwo(testlist)
print("List after multiplying = ",testlist)
感谢所有阅读此内容并想到答案的人。我的实际代码也有错误检查和内容,我不关心程序在垃圾邮件中传递会发生什么,因为这是一个非常具体的功能。
这个问题最初将它作为一个数组传递给C函数,所以这更接近最终:
static PyObject* LMS_module_timesTwo(PyObject *self, PyObject *args)
{
int i, numLines;
PyObject *listObj, *numObj;
unsigned int n;
unsigned int carray[64]; // this has to be big enough!
n = PyTuple_Size(args);
if (1 == n) {
/* argument 1 should be an list of integers */
listObj = PyTuple_GetItem(args, 0);
/* get the number of elements in the list */
numLines = PyList_Size(listObj);
/* should raise an error here. */
if (numLines < 0) return NULL; /* Not a list */
for (i=0; i<numLines; i++) {
numObj = PyList_GetItem(listObj, i);
carray[i] = PyLong_AsUnsignedLong(PyNumber_Long(numObj));
}
/* Do the actual work on the array */
someCfunction(carry); // this modifies the array somehow
for (i=0; i<numLines; i++) {
PyList_SetItem(listObj, i, Py_BuildValue("i", carray[i]));
}
} else {
PyErr_SetString(PyExc_ValueError, "Function expects one argument");
return NULL;
}
return PyLong_FromLong(1);
}