En Fri, 02 May 2008 00:26:38 -0300, grbgooglefan <[EMAIL PROTECTED]> escribió:

On Apr 22, 7:54 am, "Gabriel Genellina" <[EMAIL PROTECTED]>
wrote:

If you have a C function that receives a PyCObject, just include the  
relevant headers (cobject.h) and you can retrieve the original pointer  
using PyCObject_AsVoidPtr:


This works. But only once, means if I try to use this object second
time in Python function it causes crash.

What I am doing in my program is that I am putting STL map in a
structure & passing that structure as object to a Python function
alongwith other agurments of that Python function. This briefly as
below:

// In pyinterface.h file:---
typedef hash_map<char*,int> Elements;
typedef hash_map<char*,Elements*,StringHash,eqstr>
PerExchGroupsElementsTable;
typedef struct capsule {
        PerExchGroupsElementsTable* refgrps;
} *pcapsule;

// In pyinterface.cpp file:---
numvars = // value set depending on number of variables of that python
function
PyObject *pTuple = PyTuple_New(numvars);

// Set variables as below:
for(nCtr = 0; nCtr < numvars; nCtr++){
     slot = prul->pVarLst[nCtr].slot;
     ndtyp = ordvars[slot].dtype;
     switch(ndtyp){
       case(INT_T):
PyTuple_SetItem(pTuple,nCtr,PyInt_FromLong(ordvars[slot].nvalue));
           break;
       case(FLOAT_T):
PyTuple_SetItem(pTuple,nCtr,PyFloat_FromDouble(ordvars[slot].fvalue));
           break;
       case(STRING_T):
PyTuple_SetItem(pTuple,nCtr,PyString_FromString(ordvars[slot].cvalue));
           break;
       default:
           printf("\nUnknown data type [%d] for %s\n",ndtyp,prul-
pVarLst[nCtr].var);
           bUnknownDataType = true;
           break;
     }
     if(bUnknownDataType){
        ret = -1;
        break;
     }
}

// Then set the C++ object as below:
if(ret == 0){
    capsule grpob;
    if(pGroups){
      grpob.refgrps = pGroups; // pGroups is pointer to
PerExchGroupsElementsTable map & is global.
      int ret = PyTuple_SetItem(pTuple,
(numvars-1),PyCObject_FromVoidPtr((void *)&grpob, NULL));
    }

This look suspicious - what if !pGroups? You can't leave a tuple item uninitialized - if you create a tuple with PyTuple_New(3), then you have to fill the 3 items. And beware of that local variable grpob - you're using a pointer to it, and it won't be valid when execution goes out of this block. You must ensure that nobody stores a reference to it.
And you should decref the tuple even if this block isn't executed.

    PyObject *ptr = PyObject_GetAttrString(_pPyModule,fname);
    if(PyErr_Occurred() || *ptr == NULL){
        printf("PyObject_GetAttrString failed:%s",fname);
        return;
    }
    if(!PyCallable_Check(*ptr)){
       printf("%s not a callable Python code\n",fname);
       Py_XDECREF(*ptr);
       *ptr = NULL;
       return;
    }

All those *ptr should be ptr (the compiler should issue a lot of warnings, I presume?)

What happens is that when Python function TSE581 gets called from my C
Program via PyObject_CallObject (as shown at top of this post), co1
function works fine & can access the map pointer properly.
But when next function like1 gets called, crash happens.

My queries are & things on which I need help are:
1) Is there anything wrong I am doing when I am passing the C-Object
from my C++ code->Python -> C++ code again?

I see nothing obviously wrong, except the above notes. If you get warnings from the C++ compiler, try to fix all of them.

2) Am I missing to increase or decrease the reference count somewhere.

In case of error you exit early but without releasing some existing objects. (Sometimes a goto statement *is* the right thing to do)

3) I dont want map pointer to be ever freed because it is Process
level data structure & requried at every execution of these Python
functions. How do I avoid its cleanup when it gets passed to Python &
Python cleans up those objects.

Python will do nothing with the pointer inside a PyCObject - unless you want to, and pass a cleanup function as the second argument to the PyCObject constructor.

--
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to