Python extension in C - going lists back and forth

I have a C library for a device that includes features such as:

int GetDevInfo(int *devices);

In this case, the devices are an array of integers that could be defined as follows:

int devices[10]

The function will go through the hardware bus to search for active devices. When he finds them, he will put the device number in the next available place in devices[]. So, for example, before scanning:

devices = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}and the global variable DeviceCountknows that there are 0 active. The function does its magic and decides that devices 5 and 8 are active. So:

devices = {5, 8, 0, 0, 0, 0, 0, 0, 0, 0}and DeviceCountknows that there are 2.

I want the Python function to be something like:

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)

When he returns, it DeviceCountcan be set to 2, and the devices look like this:

[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 C.

Thannks , , !

+4
1

, ...

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);
}
0

Source: https://habr.com/ru/post/1681992/


All Articles