Tengo el siguiente código C que llama a la biblioteca API de Python:
PyObject *obj; PyObject *arguments; arguments = PyTuple_New(2); PyTuple_SetItem(arguments, 0, PyLong_FromLongLong(10)); PyTuple_SetItem(arguments, 1, PyLong_FromLongLong(20)); obj = PyObject_CallObject(my_function, arguments); // should "obj" be released after being used? PyLong_AsLongLong(obj); Py_DECREF(arguments); // is this instruction necessary? Tengo dos preguntas (ambas están en el código como comentarios), a saber: 1) ¿debería liberarse la variable obj después de usarla (en caso afirmativo, cómo se hace esto?) y 2) ¿necesitamos disminuir el contador de referencia de la variable? arguments (es decir, ¿necesitamos Py_DECREF(arguments); )? ¡Gracias por toda la ayuda de antemano!
Debe leer https://docs.python.org/3/c-api/intro.html#objects-types-and-reference-counts , que describe la forma correcta de manejar el recuento de referencias con la API de Python C. Siguiendo las reglas allí descritas, el código correcto para tu situación sería el siguiente.
PyObject *obj; PyObject *arguments; arguments = PyTuple_New(2); // this returns a new reference // You don't need to Py_DECREF() the return values of PyLong_FromLongLong() // because PyTuple_SetItem() steals a reference. PyTuple_SetItem(arguments, 0, PyLong_FromLongLong(10)); PyTuple_SetItem(arguments, 1, PyLong_FromLongLong(20)); obj = PyObject_CallObject(my_function, arguments); // this returns a new reference PyLong_AsLongLong(obj); Py_DECREF(arguments); // this is necessary because a new reference was created earlier Py_DECREF(obj); // this is necessary because a new reference was created earlier Tenga en cuenta que no he agregado ninguna verificación de errores. Algunas de estas funciones pueden devolver NULL en caso de error, por lo que sería conveniente verificarlas.