Passage d’une liste Python à une fonction C à l’aide de l’API Python / C

J’ai récemment commencé à utiliser l’API Python / C pour créer des modules pour Python à l’aide de code C. J’ai essayé de passer une liste de nombres Python à une fonction C sans succès:

asdf_module.c

#include  #include  #include  #include  int _asdf(int low, int high, double *pr) // ... for (i = 0; i < range; i++) { printf("pr[%d] = %f\n", i, pr[i]); } // ... return 0; } static PyObject* asdf(PyObject* self, PyObject* args) { int low, high; double *pr; // maybe something about PyObject *pr ? if (!PyArg_ParseTuple(args, "iiO", &low, &high, &pr)) return NULL; // how to pass list pr to _asdf? return Py_BuildValue("i", _asdf(low, high, pr)); } static PyMethodDef AsdfMethods[] = { {"asdf", asdf, METH_VARARGS, "..."}, {NULL, NULL, 0, NULL} }; PyMODINIT_FUNC initasdf(void) { (void) Py_InitModule("asdf", AsdfMethods); } 

Construire le module avec setup.py :

 from distutils.core import setup, Extension module1 = Extension('asdf', sources = ['asdf_module.c']) setup (name = 'asdf', version = '1.0', description = 'This is a demo package', ext_modules = [module1]) 

Utilisation du module dans test_module.py :

 import asdf print asdf.asdf(-2, 3, [0.7, 0.0, 0.1, 0.0, 0.0, 0.2]) 

Cependant, ce que j’ai comme sortie est:

pr [0] = 0.000000

pr [1] = 0.000000

pr [2] = 0.000000

pr [3] = 0.000000

pr [4] = 0.000000

pr [5] = -nan

De plus, au lieu de _asdf renvoyant 0, comment peut-il renvoyer un tableau de n valeurs (où n est un nombre fixe)?

Cet exemple va vous montrer comment

  1. Obtenir la longueur de la liste
  2. Allouer du stockage pour un tableau de double
  3. Obtenez chaque élément de la liste
  4. Convertir chaque élément en double
  5. Stocker chaque élément converti dans le tableau

Voici le code:

 #include "Python.h" int _asdf(double pr[], int length) { for (int index = 0; index < length; index++) printf("pr[%d] = %f\n", index, pr[index]); return 0; } static PyObject *asdf(PyObject *self, PyObject *args) { PyObject *float_list; int pr_length; double *pr; if (!PyArg_ParseTuple(args, "O", &float_list)) return NULL; pr_length = PyObject_Length(float_list); if (pr_length < 0) return NULL; pr = (double *) malloc(sizeof(double *) * pr_length); if (pr == NULL) return NULL; for (int index = 0; index < pr_length; index++) { PyObject *item; item = PyList_GetItem(float_list, index); if (!PyFloat_Check(item)) pr[index] = 0.0; pr[index] = PyFloat_AsDouble(item); } return Py_BuildValue("i", _asdf(pr, pr_length)); } 

REMARQUE: les espaces et les accolades sont supprimés pour empêcher le défilement du code.

Programme de test

 import asdf print asdf.asdf([0.7, 0.0, 0.1, 0.0, 0.0, 0.2]) 

Sortie

 pr[0] = 0.700000 pr[1] = 0.000000 pr[2] = 0.100000 pr[3] = 0.000000 pr[4] = 0.000000 pr[5] = 0.200000 0