Segmentation fault in PyArray_SimpleNewFromData - python

I am looking to pass an array from C++ to Python using C-API. By looking at various topics here, I came to know that I should be using PyArray_SimpleNewFromData method. When I am trying to implement on a very small array, I am getiing a segmentation fault in my code which I am not able to detect. Can anyone help me with this issue?
C++ code :
void init_numpy()
{
import_array();
}
int main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *pArgs, *pXVec, *xarr1;
PyObject *c ;
PyObject *pValue1 ;
int fArray[2] = {10,1} ;
PyObject *p = NULL ;
npy_intp m1 = 2;
Py_Initialize();
PySys_SetArgv(argc, argv);
init_numpy();
pName = PyString_FromString(argv[1]);
pModule = PyImport_Import(pName);
printf("check0\n");
pDict = PyModule_GetDict(pModule);
printf("check1\n");
pFunc = PyDict_GetItemString(pDict, argv[2]);
printf("check2\n");
c = PyArray_SimpleNewFromData(1,&m1,NPY_INT,fArray);
printf("check3\n");
pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs,0,c);
pValue = PyObject_CallObject(pFunc, pArgs);
if (pArgs != NULL)
{
Py_DECREF(pArgs);
}
// Clean up
Py_DECREF(pModule);
Py_DECREF(pName);
// Finish the Python Interpreter
Py_Finalize();
return 0;
}
Python Code:
import numpy as np
import scipy.io
def main(a):
print a
Output on verbose :
check0
check1
check2
Segmentation fault (core dumped)

Related

Passing array/tuple from python back to c++

I am trying to pass a list to python from cpp and taking it back. Initially I tried to pass a single value and get back one value. It worked. Now I am trying to pass the complete array/list Below is my cpp code:
#include <iostream>
#include <Python.h>
#include <numpy/arrayobject.h>
#include <typeinfo>
using namespace std;
int main()
{
Py_Initialize();
PyObject *sys = PyImport_ImportModule("sys");
PyObject *path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyString_FromString("."));
PyObject *pName, *pModule, *pDict, *pFunc, *pArgs, *pValue;
// Build the name object
pName = PyString_FromString("mytest");
// Load the module object
pModule = PyImport_Import(pName);
// pDict is a borrowed reference
pDict = PyModule_GetDict(pModule);
// pFunc is also a borrowed reference
pFunc = PyObject_GetAttrString(pModule, "stuff");
if (!PyCallable_Check(pFunc))
PyErr_Print();
PyObject *list = PyList_New (5);
Py_ssize_t size = PyList_GET_SIZE(list);
for(Py_ssize_t s = 0; s < size; s++ )
{
PyList_SetItem(list, s, Py_BuildValue("d", 2.5));
}
PyObject* result = PyObject_CallObject(pFunc, list);
if(result==NULL)
{cout << "FAILED ..!!" << endl;}
cout << result << endl;;
return 0;
}
I am always getting "FAILED..!!".
Here is my mytest.py
def stuff(a):
x=a
return x
Any suggestions where I might be going wrong?
From the documentation:
PyObject* PyObject_CallObject(PyObject *callable, PyObject *args)
This is the equivalent of the Python expression: callable(*args).
Whereas PyObject_CallFunctionObjArgs is documented as:
PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ..., NULL)
This is the equivalent of the Python expression: callable(arg1, arg2, ...).
So change your call to the following:
PyObject* result = PyObject_CallFunctionObjArgs(pFunc, list, NULL);
(or you could wrap your list inside another list and keep on using CallObject, but this is by far the easier solution)

how to pass a frame buffer from C to Python using OpenCV

I had an image processing function (IMP) written in Python using OpenCV lib.
Now I would like to call IMP from C code:
#include "/usr/include/python2.7/Python.h"
int main()
{
PyObject *pName, *pModule, *pDict, *pFun, *pValue, main_module;
// Initialize the Python Interpreter
Py_Initialize();
// Build the name object
pName = PyString_FromString("test");
if(pName)printf("OK\n");
// Load the module object
pModule = PyImport_Import(pName);
// pFunc is also a borrowed reference
pFun = PyObject_GetAttrString(pModule, "IMP");
if (PyCallable_Check(pFun))
{
//PyObject_CallObject(pFun, NULL);
PyObject_CallFunction(pFun,"o",framebuffer);
}
else
{
PyErr_Print();
}
// Clean up
Py_DECREF(pModule);
Py_DECREF(pName);
Py_DECREF(pFun);
// Finish the Python Interpreter
Py_Finalize();
getchar();
return 0;
}
How do I prepare "framebuffer" to pass into my IMP python function?
could anyone help to show me an example image packaged in an object understood by CV2 and pass it to IMP using the above example C code? Thanks a lot for your help.
I think I found what I need: just create a template "framebuffer" in my test.py:
import numpy as np
import cv2
framebuffer = cv2.imread('pic.jpg',cv2.IMREAD_COLOR)
def IMP(p):
print "I am here!"
print "image.shape h,w,d=",p.shape
cv2.imshow("picture",p)
cv2.waitKey(0)
cv2.destroyAllWindows()
and then in my test.c, I grep the "framebuffer" from pDict for further manipulation then call IMP:
#include "/usr/include/python2.7/Python.h"
#include <numpy/arrayobject.h>
int main()
{
PyObject *pName, *pModule, *pDict, *pFun, *pValue, *pArgs, *pFB;
int i,j;
// Initialize the Python Interpreter
Py_Initialize();
// Build the name object
pName = PyString_FromString("test");
if(pName)printf("OK\n");
// Load the module object
pModule = PyImport_Import(pName);
// pDict is a borrowed reference
pDict = PyModule_GetDict(pModule);
// pFunc is also a borrowed reference
pFun = PyDict_GetItemString(pDict, "IMP");
pFB = PyDict_GetItemString(pDict, "framebuffer");
if (pFB != NULL)
printf("got the framebuffer as pFB!\n");
//copy a new framebuffer into pFB here!!!
uint8_t *ptr;
ptr = PyArray_DATA(pFB);
int col,row,color;
int NCOL = 0, NROW = 0, NCLR = 0;
int ndim=0;
ndim = PyArray_NDIM(pFB);
NROW = PyArray_DIM(pFB,0);
NCOL = PyArray_DIM(pFB,1);
NCLR = PyArray_DIM(pFB,2);
for (row=0;row<NROW;row++)
for (col=0;col<NCOL;col++)
for (color=0;color<NCLR;color++)
{
*ptr = pixel_value; //copy your framebuffer pixel value to pFB!!!
ptr++;
}
pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs,0,pFB);
if (PyCallable_Check(pFun))
{
PyObject_CallObject(pFun, pArgs); //call python IMP with updated framebuffer!!!
}
else
{
PyErr_Print();
}
// Clean up
Py_DECREF(pModule);
Py_DECREF(pName);
//Py_DECREF(pDict); //do not decref on pDict because it is borrowed ref, otherwise it will crash Py_Finalize()!!!
//Py_DECREF(pArgs);
//Py_DECREF(pFun);
//Py_DECREF(pFB);
// Finish the Python Interpreter
Py_Finalize();
return 0;
}
That's it!

Embedding python into C++ does not work as expected

I am embedding Python into a C++ application.
When I run the following piece of C++ code, which returns me the timestamp, it works fine.
Py_Initialize();
std::string strModule = "time"; // module to be loaded
pName = PyString_FromString(strModule.c_str());
pModule = PyImport_Import(pName); // import the module
pDict = PyModule_GetDict(pModule); // get all the symbols in the module
pFunc = PyDict_GetItemString(pDict, "time"); // get the function we want to call
// Call the function and get the return in the pValue
pValue = PyObject_CallObject(pFunc, NULL);
if (pValue == NULL){
printf('Something is wrong !');
return 0;
}
printf("Return of python call : %d\n", PyInt_AsLong(pValue)); // I get the correct timestamp
Py_Finalize();
Now I want to get the sys.path. But the similar code throws me error:
Py_Initialize();
std::string strModule = "sys"; // module to be loaded
pName = PyString_FromString(strModule.c_str());
pModule = PyImport_Import(pName); // import the module
pDict = PyModule_GetDict(pModule); // get all the symbols in the module
pFunc = PyDict_GetItemString(pDict, "path"); // get the function we want to call
// Call the function and get the return in the pValue
pValue = PyObject_CallObject(pFunc, NULL);
if (pValue == NULL){
printf('Something is wrong !'); // I end up here, why pValue is NULL?
return 0;
}
printf("Return of python call : %d\n", PyInt_AsLong(pValue));
Py_Finalize();
I guess the problem is that time.time() is a function call whereas sys.path is a variable. If that is the case:
How to get the result of a variable?
How to properly translate the result (in this case a list) to something meaningful in C++ for e.g. an array of strings?
If not, how to proceed? I am using Python 2.7.6
Thanks.
Your problem is that PyDict_GetItemString(pDict, "path") will return python list and it is not callable. And when you execute PyObject_CallObject(pFunc, NULL); you will execute it. This is equal to sys.path().
This should work:
PyObject *pName, *pModule, *pDict, *list, *pValue, *item;
int n, i;
char *name;
Py_Initialize();
std::string strModule = "sys"; // module to be loaded
pName = PyString_FromString(strModule.c_str());
pModule = PyImport_Import(pName); // import the module
pDict = PyModule_GetDict(pModule); // get all the symbols in the module
list = PyDict_GetItemString(pDict, "path"); // get python list
n = PyList_Size(list);
if (n < 0)
return -1; /* Not a list */
for (i = 0; i < n; i++) { // iterate over list
item = PyList_GetItem(list, i); /* Can't fail */
if (!PyString_Check(item)) continue; /* Skip non-string */
name = PyString_AsString(item);
std::puts(name);
}
Py_Finalize();
return 0;
Full code here.

Embedding Python into C example not working

I'm following this tutorial on Embedding Python on C, but their Pure Embedding example is not working for me.
I have on the same folder (taken from the example):
call.c
#include <Python.h>
int
main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pDict, *pFunc;
PyObject *pArgs, *pValue;
int i;
if (argc < 3) {
fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
return 1;
}
Py_Initialize();
pName = PyString_FromString(argv[1]);
/* Error checking of pName left out */
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, argv[2]);
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(argc - 3);
for (i = 0; i < argc - 3; ++i) {
pValue = PyInt_FromLong(atoi(argv[i + 3]));
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return 1;
}
/* pValue reference stolen here: */
PyTuple_SetItem(pArgs, i, pValue);
}
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL) {
printf("Result of call: %ld\n", PyInt_AsLong(pValue));
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return 1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
return 1;
}
Py_Finalize();
return 0;
}
multiply.py
def multiply(a,b):
print "Will compute", a, "times", b
c = 0
for i in range(0, a):
c = c + b
return c
And I compile and run like this:
$ gcc $(python-config --cflags) call.c $(python-config --ldflags) -o call
call.c: In function ‘main’:
call.c:6:33: warning: unused variable ‘pDict’ [-Wunused-variable]
PyObject *pName, *pModule, *pDict, *pFunc;
^
# This seems OK because it's true that pDict is not used
$ ./call multiply multiply 3 2
ImportError: No module named multiply
Failed to load "multiply"
Why can't it load multiply module?
Example doesn't show filenames nor paths. Can it be a path problem?
Thanks a lot.
Try setting PYTHONPATH:
export PYTHONPATH=`pwd`
Really, the example should have PySys_SetPath("."); after initialization.

Embedding the Python Interpreter and using SWIG

I have a solution in VisualStudio that contains two projects. The first project is a C++ console application with Pure Embedding as follows:
#include <Python.h>
int main(int argc, char *argv[]){
PyObject *pName, *pModule, *pDict, *pFunc;
PyObject *pArgs, *pValue;
int i;
if (argc < 3) {
fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
return 1;
}
Py_Initialize();
pName = PyUnicode_FromString(argv[1]);
/* Error checking of pName left out */
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, argv[2]);
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(argc - 3);
for (i = 0; i < argc - 3; ++i) {
pValue = PyLong_FromLong(atoi(argv[i + 3]));
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return 1;
}
/* pValue reference stolen here: */
PyTuple_SetItem(pArgs, i, pValue);
}
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL) {
printf("Result of call: %ld\n", PyLong_AsLong(pValue));
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return 1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
return 1;
}
Py_Finalize();
return 0;}
When running a python file any works perfectly.
The second project contains some C++ classes compiled with SWIG. This project works perfectly using the Python script as below.
import example
x = 42
y = 105
example.gcd = g (x, y)
My problem is when the console application needs to run a python script that imports classes from the SWIG. If I use the python lib python32.lib works commenting on some parts of the code as "Py_DECREF (pArgs)" but I can only run once the python script, the second attempt, an error occurs the read access of memory. If I use python32_d.lib the construction of the modules do not work if the file import python SWIG:
pName = PyUnicode_FromString(argv[1]);
pModule = PyImport_Import(pName);
NOTE: I need to compile in DEBUG mode and not in RELEASE mode.

Categories