Hi!
I'm trying to access python objects from c++. It works once. Second
time it hangs.
Does someone have any clue or some example code or pointer?
Thanks!
/Karim
Here are some python classes:
--------------------------------------------------------------------------------------------------
import portage
class PortageInterfac e:
def __init__(self):
self.vartree = portage.db[portage.root]["vartree"]
self.porttree = portage.db[portage.root]["porttree"]
def installedPackag es(self):
return self.vartree.db api.cp_all()
def installedPackag esVersion(self) :
t = []
for cpv in self.vartree.db api.cpv_all():
mysplit = portage.catpkgs plit(cpv)
mypkg = "/".join(mysp lit[:3])
if mysplit[3] != "r0":
mypkg = mypkg + "-" + mysplit[3]
t.append( mypkg )
return t
def portagePackages (self):
return self.porttree.d bapi.cp_all()
def allPortagePacka ges(self):
t = []
t = self.porttree.d bapi.cp_all()
t += self.vartree.db api.cp_all()
return t
def allPackagesVers ion(self):
t = []
for x in self.porttree.d bapi.cp_all():
t.extend( self.porttree.d bapi.cp_list(x) )
return t
def getAllPackageDa ta(self, db, keys):
rval = {}
cplist = db.cp_all()
cplist.sort()
for cp in cplist:
for cpv in db.cp_list(cp):
rval[cpv] = db.aux_get(cpv, keys)
return rval
def allPackagesData (self):
testdata = {}
testdata = self.getAllPack ageData(self.po rttree.dbapi,
["DESCRIPTIO N", "HOMEPAGE", "LICENSE", "KEYWORDS", "IUSE", "SLOT"])
t = []
for cpv in testdata.keys() :
mysplit = portage.catpkgs plit(cpv)
mypkg = "/".join(mysp lit[:3])
if mysplit[3] != "r0":
mypkg = mypkg + "-" + mysplit[3]
t.append( mypkg )
for v in testdata[cpv]:
t.append( v )
return t
--------------------------------------------------------------------------------------------------
And the c++ class executed inside a thread:
--------------------------------------------------------------------------------------------------
#include "pythonizer .h"
#ifdef _XOPEN_SOURCE
#undef _XOPEN_SOURCE
#endif
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#include <Python.h>
#include <qstringlist. h>
#include <qfile.h>
#include <kdebug.h>
#define foreach( x ) \
for( QStringList::Co nstIterator it = x.begin(), end = x.end(); it !=
end; ++it )
#define LINE_INFO " ( " << k_funcinfo << "Line: " << __LINE__ << " )"
<< endl
#define DEBUG_LINE_INFO kdDebug() << LINE_INFO
Pythonizer::Pyt honizer( const char *file, char *pyClass )
: m_file( file ), m_pyClass( pyClass )
{
kdDebug() << "Pythonizer::Py thonizer" << endl;
}
Pythonizer::~Py thonizer()
{
kdDebug() << "Pythonizer::~P ythonizer" << endl;
}
QStringList Pythonizer::get Packages( char *pyModule )
{
DEBUG_LINE_INFO ;
// Initialize the Python Interpreter
Py_Initialize() ;
PyObject *pName, *pModule, *pDict, *pValue, *pClass, *pInstance;
// Build the name object
pName = PyString_FromSt ring( m_file );
DEBUG_LINE_INFO ;
if ( PyErr_Occurred( ) ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
// Load the module object
pModule = PyImport_Import ( pName );
DEBUG_LINE_INFO ;
if ( PyErr_Occurred( ) ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
// pDict is a borrowed reference
pDict = PyModule_GetDic t( pModule );
DEBUG_LINE_INFO ;
if ( PyErr_Occurred( ) ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
// Build the name of a callable class
pClass = PyDict_GetItemS tring( pDict, m_pyClass );
DEBUG_LINE_INFO ;
if ( PyErr_Occurred( ) ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
// Create an instance of the class
if ( PyCallable_Chec k( pClass ) ) {
pInstance = PyObject_CallOb ject( pClass, NULL );
DEBUG_LINE_INFO ;
if ( PyErr_Occurred( ) ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
}
else {
kdDebug() << "Can not create python class instance." << endl;
return QStringList::QS tringList();
}
// Call a method of the class with two parameters
pValue = PyObject_CallMe thod( pInstance, pyModule, NULL );
if ( PyErr_Occurred( ) ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
PyObject *iterator = PyObject_GetIte r( pValue );
if ( iterator == NULL ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
QStringList packageList;
PyObject *item;
while ( item = PyIter_Next( iterator ) ) {
packageList << PyString_AsStri ng( item );
/* release reference when done */
Py_DECREF( item );
}
Py_DECREF( iterator );
// Clean up
Py_DECREF( pValue );
Py_DECREF( pInstance );
Py_DECREF( pClass );
// Py_DECREF( pDict );
Py_DECREF( pModule );
Py_DECREF( pName );
PyErr_Clear();
DEBUG_LINE_INFO ;
// Finish the Python Interpreter
Py_Finalize();
return packageList;
}
--------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
#ifndef PYTHONIZER_H
#define PYTHONIZER_H
#include <qstringlist. h>
class Pythonizer{
public:
Pythonizer( const char *file, char *pyClass );
~Pythonizer();
QStringList getPackages( char *pyModule );
private:
QString m_file;
QString m_pyClass;
};
#endif
--------------------------------------------------------------------------------------------------
I'm trying to access python objects from c++. It works once. Second
time it hangs.
Does someone have any clue or some example code or pointer?
Thanks!
/Karim
Here are some python classes:
--------------------------------------------------------------------------------------------------
import portage
class PortageInterfac e:
def __init__(self):
self.vartree = portage.db[portage.root]["vartree"]
self.porttree = portage.db[portage.root]["porttree"]
def installedPackag es(self):
return self.vartree.db api.cp_all()
def installedPackag esVersion(self) :
t = []
for cpv in self.vartree.db api.cpv_all():
mysplit = portage.catpkgs plit(cpv)
mypkg = "/".join(mysp lit[:3])
if mysplit[3] != "r0":
mypkg = mypkg + "-" + mysplit[3]
t.append( mypkg )
return t
def portagePackages (self):
return self.porttree.d bapi.cp_all()
def allPortagePacka ges(self):
t = []
t = self.porttree.d bapi.cp_all()
t += self.vartree.db api.cp_all()
return t
def allPackagesVers ion(self):
t = []
for x in self.porttree.d bapi.cp_all():
t.extend( self.porttree.d bapi.cp_list(x) )
return t
def getAllPackageDa ta(self, db, keys):
rval = {}
cplist = db.cp_all()
cplist.sort()
for cp in cplist:
for cpv in db.cp_list(cp):
rval[cpv] = db.aux_get(cpv, keys)
return rval
def allPackagesData (self):
testdata = {}
testdata = self.getAllPack ageData(self.po rttree.dbapi,
["DESCRIPTIO N", "HOMEPAGE", "LICENSE", "KEYWORDS", "IUSE", "SLOT"])
t = []
for cpv in testdata.keys() :
mysplit = portage.catpkgs plit(cpv)
mypkg = "/".join(mysp lit[:3])
if mysplit[3] != "r0":
mypkg = mypkg + "-" + mysplit[3]
t.append( mypkg )
for v in testdata[cpv]:
t.append( v )
return t
--------------------------------------------------------------------------------------------------
And the c++ class executed inside a thread:
--------------------------------------------------------------------------------------------------
#include "pythonizer .h"
#ifdef _XOPEN_SOURCE
#undef _XOPEN_SOURCE
#endif
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#include <Python.h>
#include <qstringlist. h>
#include <qfile.h>
#include <kdebug.h>
#define foreach( x ) \
for( QStringList::Co nstIterator it = x.begin(), end = x.end(); it !=
end; ++it )
#define LINE_INFO " ( " << k_funcinfo << "Line: " << __LINE__ << " )"
<< endl
#define DEBUG_LINE_INFO kdDebug() << LINE_INFO
Pythonizer::Pyt honizer( const char *file, char *pyClass )
: m_file( file ), m_pyClass( pyClass )
{
kdDebug() << "Pythonizer::Py thonizer" << endl;
}
Pythonizer::~Py thonizer()
{
kdDebug() << "Pythonizer::~P ythonizer" << endl;
}
QStringList Pythonizer::get Packages( char *pyModule )
{
DEBUG_LINE_INFO ;
// Initialize the Python Interpreter
Py_Initialize() ;
PyObject *pName, *pModule, *pDict, *pValue, *pClass, *pInstance;
// Build the name object
pName = PyString_FromSt ring( m_file );
DEBUG_LINE_INFO ;
if ( PyErr_Occurred( ) ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
// Load the module object
pModule = PyImport_Import ( pName );
DEBUG_LINE_INFO ;
if ( PyErr_Occurred( ) ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
// pDict is a borrowed reference
pDict = PyModule_GetDic t( pModule );
DEBUG_LINE_INFO ;
if ( PyErr_Occurred( ) ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
// Build the name of a callable class
pClass = PyDict_GetItemS tring( pDict, m_pyClass );
DEBUG_LINE_INFO ;
if ( PyErr_Occurred( ) ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
// Create an instance of the class
if ( PyCallable_Chec k( pClass ) ) {
pInstance = PyObject_CallOb ject( pClass, NULL );
DEBUG_LINE_INFO ;
if ( PyErr_Occurred( ) ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
}
else {
kdDebug() << "Can not create python class instance." << endl;
return QStringList::QS tringList();
}
// Call a method of the class with two parameters
pValue = PyObject_CallMe thod( pInstance, pyModule, NULL );
if ( PyErr_Occurred( ) ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
PyObject *iterator = PyObject_GetIte r( pValue );
if ( iterator == NULL ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QS tringList();
}
QStringList packageList;
PyObject *item;
while ( item = PyIter_Next( iterator ) ) {
packageList << PyString_AsStri ng( item );
/* release reference when done */
Py_DECREF( item );
}
Py_DECREF( iterator );
// Clean up
Py_DECREF( pValue );
Py_DECREF( pInstance );
Py_DECREF( pClass );
// Py_DECREF( pDict );
Py_DECREF( pModule );
Py_DECREF( pName );
PyErr_Clear();
DEBUG_LINE_INFO ;
// Finish the Python Interpreter
Py_Finalize();
return packageList;
}
--------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
#ifndef PYTHONIZER_H
#define PYTHONIZER_H
#include <qstringlist. h>
class Pythonizer{
public:
Pythonizer( const char *file, char *pyClass );
~Pythonizer();
QStringList getPackages( char *pyModule );
private:
QString m_file;
QString m_pyClass;
};
#endif
--------------------------------------------------------------------------------------------------
Comment