I am attempting to automate the building of binding for a 3rd party library. The functions I'm wrapping all return an integer of whether they failed and output are passed as pointers. There can be multiple return values. So the code that I generate has a PyObject* called python__return_val that I use for returning. In the 'wrapped_foo' function below you see I build the return value with Py_BuildValue and "OO" as the format. For every output I have I do a C to Python conversion and add another 'O' to the format. What I'm wondering is if I can use the same logic when wrapping functions that only return one value like the wrapped_bar function below.
So for multiples, I wind up doing this which is fine. python__x = Py_BuildValue("s", x) python__y = Py_BuildValue("s", y) python__return_val = Py_BuildValue("OO", python__x, python__y); But for single returns I do something like this.... I realize that the 2 lines below are pointless, but are they causing a memory leak or problems with reference counting? python__x = Py_BuildValue("s", x) python__return_val = Py_BuildValue("O", python__x); Are python__x and python__return_val the same object, a copy of the object? Would python__x ever get garbage collected? Should my code generator detect when there is only one output and not go through the extra step? Thanks, ~Eric static PyObject * wrapped_foo(PyObject *self, PyObject *args) { int wrapp_fail; // C types int x; const char* some_str; int* y; char** abc; // Python types PyObject* python__return_val; PyObject* python__y; PyObject* python__abc; // Get Python args if (!PyArg_ParseTuple(args, "is", &x, &some_str)) return NULL; // Wrapped Call wrapp_fail = foo(x, some_str, &y, &abc); if(wrapp_fail != 0){ return NULL; } // Convert output to Python types python__y = Py_BuildValue("i", y) python__abc = Py_BuildValue("s", abc) // Build Python return value python__return_val = Py_BuildValue("OO", python__y, python__abc); // Memory free's MEM_free(abc) return python__return_val; } static PyObject * wrapped_bar(PyObject *self, PyObject *args) { int wrapp_fail; // C types int a; const char* b; char** c; // Python types PyObject* python__return_val; PyObject* python__c; // Get Python args if (!PyArg_ParseTuple(args, "is", &a, &b)) return NULL; // Wrapped Call wrapp_fail = bar(a, b, &c); if(wrapp_fail != 0){ return NULL; } // Convert output to Python types python__c = Py_BuildValue("s", c) // Build Python return value python__return_val = Py_BuildValue("O", python__c); // Memory free's MEM_free(c) return python__return_val; } -- http://mail.python.org/mailman/listinfo/python-list