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: > > void foo(PyObject *pyobj) > { > TOriginalType *porig; > porig = (TOriginalType *)PyCObject_AsVoidPtr(pyobj); > // do something with porig > } > -- > Gabriel Genellina- Hide quoted text - > > - Show quoted text -
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)); } PyObject *pResult = PyObject_CallObject(pfunc,pTuple); if(PyErr_Occurred()){ printf("error occured in PyObject_CallObject for %s\n",prul- >pyobj.szPyRouteName); PyErr_Print(); } else { printf("Python function passed, use its result for other purposes as designed\n"); } Py_XDECREF(pResult); Py_XDECREF(pTuple); } //---------- My Pythong module & functions in it ------------------- //PyObject* pfunc is a Python function which I compile dynamically & add to my Python module as below: // One of such dynamically compiled function is as below: char pyfunction[]=\ "def TSE581(t22,t52,t1012,ob): if(co1(ob,t22,\"TSE_FUTURE_GRP\") and like1(ob,t52,\"TSE_SECID_LST2\")):\n\ print \"result is pass\"\n\ return 1\n\ else:\n\ print \"result is fail\"\n\ return 0\n"; // function parameter "ob" in this function definition is the one which Im passing as CObject. PyObject *result = NULL; result = PyRun_String(pyfunction,Py_file_input,_pPyDictionary,_pPyDictionary); if(PyErr_Occurred() || result == NULL){ printf("Failed to compile function [%s]\n",func); PyErr_Print(); return; } Py_XDECREF(result); result = NULL; 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; } // I've created dynamically loadble Python module & multiple functions similar to above gets added dynamically to this module. // Module has functions "co1" & "like1" in module's .cpp file. These functions then use CObject - the struct capsule & map pointer in it. static PyObject* merorderrouter_co1(PyObject* self, PyObject* args) { printf("Contains function\n"); int ret=0; char *arg1=NULL, *arg2=NULL; PyObject* voidcap=NULL; if(!PyArg_ParseTuple(args, "Oss", &voidcap,&arg1,&arg2)){ printf("failed to get args\n"); if(PyErr_Occurred()) PyErr_Print(); return(PyInt_FromLong(ret)); } printf("key=%s, grpname=[%s]\n",arg1,arg2); if(voidcap && PyCObject_Check(voidcap)) printf("valid Py-C-Object\n"); else printf("NOT a valid Py-C-Object\n"); pcapsule pobj = (pcapsule)PyCObject_AsVoidPtr(voidcap); if(pobj){ PerExchGroupsElementsTable grpmap = *pobj->refgrps; if(grpmap.count(arg2)){ PerExchGroupsElementsTable::iterator grpmi = grpmap.find(arg2); Elements grpelems = *(Elements*)grpmi->second; Elements::iterator ei = grpelems.find(arg1); if(ei != grpelems.end()){ printf("has elm.\n"); ret=1; } else { printf("no elm.\n"); ret=0; } } } else { printf("pcapsule object is null from PyCObject_AsVoidPtr \n"); if(PyErr_Occurred()) PyErr_Print(); } printf("------- co returning.....\n"); return PyInt_FromLong(ret); } //======================================================= 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? 2) Am I missing to increase or decrease the reference count somewhere. 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. If want to see my Python module & the CPP code using it, I can send all my source code to you. Please help. -- http://mail.python.org/mailman/listinfo/python-list