I'm writing an app that requires a list from Python to be read into an array in C++. The problem I'm having is that I can't get my code to work under any version of Python after 2.4, and I don't think I'm using any deprecated functions. It runs fine using Python 2.4, but when I run it under 2.5+ it still compiles but I get an "EXEC BAD ACCESS" error when it gets to this line:

pDict = PyModule_GetDict(pModule);

The usage is supposed to be ./myApp python.py module

This is my code:

// call_function.c - A sample of calling python functions from C code
// 
#include <Python.h>
#include <iostream>

int main(int argc, char *argv[])
{
	int i;
	PyObject *pName, *pDict, *pFunc, *pArgs, *pValue;

	if (argc < 3) 
	{
		printf("Usage: exe_name python_source function_name\n");
		return 1;
	}

	// Initialize the Python Interpreter
	Py_Initialize();

	// Build the name object
	pName = PyString_FromString(argv[1]);

	// Load the module object
	
	PyObject* pModule = PyImport_Import(pName);
	
	
	// pDict is a borrowed reference 
	
	pDict = PyModule_GetDict(pModule);
	
	

	// pFunc is also a borrowed reference 
	pFunc = PyObject_GetAttrString(pModule, argv[2]);
	//pFunc = PyDict_GetItemString(pDict, "main");
	
	if (PyCallable_Check(pFunc)) 
	{
		
		// Prepare the argument list for the call
		if( argc > 3 )
		{
			
    			pArgs = PyTuple_New(argc - 3);
    			for (i = 0; i < argc - 3; i++)
    			{
					pValue = PyInt_FromLong(atoi(argv[i + 3]));
        			if (!pValue)
        			{
						PyErr_Print();
             			return 1;
        			}
        			PyTuple_SetItem(pArgs, i, pValue);	
    			}
			
				pValue = PyObject_CallObject(pFunc, pArgs);

				if (pArgs != NULL)
				{
					Py_DECREF(pArgs);
				}
		} else
		{
				pValue = PyObject_CallObject(pFunc, NULL);
		}
		
		if (pValue != NULL) 
		{
			
			//int* my_array = (int*) malloc(sizeof(int) * PyList_Size(pValue));
			int tupleSize = PyList_Size(pValue);
			PyObject* ss;

			for( i=0; i < tupleSize; i++ ){
			
				//my_array[i] = (int)PyList_GetItem(pValue, i);
				ss = PyList_GetItem(pValue, i);
	
				//std::cout << PyString_AsString(PyTuple_GetItem(pValue, i));
				std::cout<< "\n" <<PyInt_AsLong(ss);

			}
			//std::cout<< my_array;
			//printf("Return of call : %d\n", (int)(PyInt_AsLong(pValue)));
			Py_DECREF(pValue);
		}
		else 
		{
			PyErr_Print();
		}
	} else 
		std::cout << "\n Function not callable \n";
	{
		PyErr_Print();
	}

	// Clean up
	//Py_DECREF(pModule);
	Py_DECREF(pName);

	// Finish the Python Interpreter
	///Py_Finalize();

	char c;
	std::cin >> c;

	return 0; */
}

After this call PyObject* pModule = PyImport_Import(pName); , you should at least check if pModule is NULL, meaning that the import failed.

After this call PyObject* pModule = PyImport_Import(pName); , you should at least check if pModule is NULL, meaning that the import failed.

I did that and it does indeed return NULL under Python 2.6(on my current dev machine). Any idea why? I can't find anything about this function that seems to have changed between 2.4 & 2.6. Or, if you happen to know a work-around, that would be really helpful. Thanks!

I did that and it does indeed return NULL under Python 2.6(on my current dev machine). Any idea why? I can't find anything about this function that seems to have changed between 2.4 & 2.6. Or, if you happen to know a work-around, that would be really helpful. Thanks!

Can you import your module from the python 2.6 console ? If it works, another idea would be to print sys.path from your C++ program to check its content, something like

void print_sys_argv(){
  PyObject* sys = PyImport_ImportModule("sys"); // should check NULL
  PyObject* path = PyObject_GetAttrString(sys, "path"); // should check NULL
  Py_ssize_t n = PyList_Size(path);
  for(Py_ssize_t i = 0; i < n; ++i){
    PyObject* item = PyList_GetItem(path, i); // should check NULL
    cout << PyString_AsString(item) << "\n";
  }
  Py_XDECREF(path);
  Py_XDECREF(sys);
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.