I've recently started using the Python/C API to build modules for Python using C code. I've been trying to pass a Python list of numbers to a C function without success:
asdf_module.c
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <Python.h>
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);
}
Building the module with 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])
Using the module in test_module.py :
import asdf
print asdf.asdf(-2, 3, [0.7, 0.0, 0.1, 0.0, 0.0, 0.2])
However, what I got as an output is :
pr[0] = 0.000000
pr[1] = 0.000000
pr[2] = 0.000000
pr[3] = 0.000000
pr[4] = 0.000000
pr[5] = -nan
Also, instead of _asdf returning 0, how can it return an array of n
values (where n
is a fixed number)?
This example will show you how to
double
double
Here is the 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));
}
NOTE: White space and braces removed to keep code from scrolling.
Test program
import asdf
print asdf.asdf([0.7, 0.0, 0.1, 0.0, 0.0, 0.2])
Output
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
Addressing Concerns About Memory Leaks
People seem to be worried about the code not freeing the memory. This is just enough code to show how to convert the list to double. I wanted the code to be able to fit in the text box without scrolling, so it is not production code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With