While I commonly use C or C++ for processing signals there are not too many options available for displaying the results graphically so I have been looking at using Matplotlib for the display. The first problem I encountered is how to pass an array of floating point data from C to Python.
There are several options and a lot of forum discussions on the subject but I couldn't find a simple solution. So here is one that I developed earlier.
This example works with an Anaconda/Python v3.3 installation with the 64 bit Microsoft compiler.
See here for an introduction to Anaconda/Python v3.3 installation and calling Python from the 64 bit Microsoft compiler : http://realgonegeek.blogspot.co.uk/2013/08/how-to-embed-python-pylab-into-64bit.html.
Here is the C code :
#include <Python.h>
#include <stdio.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include "C:\Anaconda\envs\py33\Lib\site-packages\numpy\core\include\numpy\arrayobject.h"
double Array [] = {1.2, 3.4, 5.6, 7.8};
int main (int argc, char *argv[])
{
PyObject *pName, *pModule, *pDict, *pFunc, *pArgs, *pValue;
npy_intp dims[1] = { 4 };
PyObject *py_array;
Py_Initialize ();
pName = PyUnicode_FromString ("PrintArray");
// PyUnicode_FromString error checking here
pModule = PyImport_Import (pName); // Load the module object
// PyImport_Import error checking here
Py_DECREF(pName);
pFunc = PyObject_GetAttrString (pModule, "PrintArray"); // pFunc is a new reference
// PyObject_GetAttrString error checking here
import_array (); // Required for the C-API : http://docs.scipy.org/doc/numpy/reference/c-api.array.html#importing-the-api
py_array = PyArray_SimpleNewFromData (1, dims, NPY_DOUBLE, Array);
// PyArray_SimpleNewFromData error checking here
pDict = PyModule_GetDict (pModule); // pDict is a borrowed reference
pArgs = PyTuple_New (1);
PyTuple_SetItem (pArgs, 0, py_array);
pFunc = PyDict_GetItemString (pDict, "PrintArray"); // pFunc is also a borrowed reference
if (PyCallable_Check (pFunc))
{
PyObject_CallObject (pFunc, pArgs);
} else
{
printf ("Function not callable !\n");
}
Py_DECREF (py_array); // Clean up
Py_DECREF (pModule);
Py_DECREF (pDict);
Py_DECREF (pFunc);
Py_Finalize (); // Finish the Python Interpreter
return 0;
}
Here is the python script to print the contents of the array :
def PrintArray (a):
print ("Contents of a :")
print (a)
c = 0
return c
If you have found this solution useful then please do hit the Google (+1) button so that others may be able to find it as well.
Thanks for the code
ReplyDeletethe Py_DECREF(pDict); line gives
Unhandled exception at 0x1E0ABA42 (python27.dll) in pythonEmbedded2.exe: 0xC0000005: Access violation reading location 0xFEEEFEF2.
when I comment it out, it works fine.
Any ideas as to why this is ?
Hi Asanka,
ReplyDeleteNo, I don't know why this occurs. I use Anaconda and it works fine.
I'm glad it works for you when you remove the line.
All the best,
John
Hi John,
ReplyDeleteTHANKS FOR THE SOLUTION
I have two doubts,
1) How to get the array from python and use those array values in C
2) Do we need to specify the size of the array in C. How to achieve the Dynamic memory allocation using your code.
Hi Reji,
DeleteUnfortunately, I did not need to get data back from Python to C so I have not tried it. If I get a chance I will work something out and upload it.
Another option would be the SWIG API, I think this should do it.
Yes, you could malloc Array in the C code although for the example I just created a fixed size array.
John
It works great, thank you very much indeed! Have you found a way to get the array back from the python function?
DeleteThank you for your comment. Unfortunately I did not need to get data back to C so I did not work that out.
DeleteIf you do find a solution then feel free to add a link to the thread.
Good luck