8

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)?

2
  • for one, the o parameter is used to get a PyObject *. So you need to fix that up, and keep parsing. Commented Aug 21, 2016 at 10:22
  • 1
    It is preferred if you can post separate questions instead of combining your questions into one. That way, it helps the people answering your question and also others hunting for at least one of your questions. If you have another question, I would suggest going up to the little Ask Question button in the top right hand corner. Thanks! Commented Aug 21, 2016 at 18:46

1 Answer 1

14

This example will show you how to

  1. Get the length of the list
  2. Allocate storage for an array of double
  3. Get each element of the list
  4. Convert each element to a double
  5. Store each converted element in the array

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Make sure to free pr (allocated with malloc) after you're done, otherwise there's a memory leak.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.