Para extraer un argumento de una invocación del método, es necesario mirar las funciones documentadas en Parsing arguments and building values, como PyArg_ParseTuple
. (Eso es por si solo está tomando argumentos posicionales! Hay otros para argumentos posicionales y de palabras clave, etc.)
El objeto que obtiene de PyArg_ParseTuple
no tiene un recuento de referencias incrementado. Para funciones C simples, probablemente no tenga que preocuparse por esto. Si está interactuando con otras funciones de Python/C, o si está liberando el bloqueo de intérprete global (es decir, permitiendo el enhebrado), debe pensar detenidamente sobre la propiedad del objeto.
static PyObject *
_sayhello_obj(PyObject *self, PyObject *args)
{
PyObject *obj = NULL;
// How can I fill obj?
static char fmt_string = "O" // For "object"
int parse_result = PyArg_ParseTuple(args, fmt_string, &obj);
if(!parse_res)
{
// Don't worry about using PyErr_SetString, all the exception stuff should be
// done in PyArg_ParseTuple()
return NULL;
}
// Of course, at this point you need to do your own verification of whatever
// constraints might be on your argument.
Para llamar a un método en un objeto, es necesario utilizar ya sea PyObject_CallMethod
o PyObject_CallMethodObjArgs
, dependiendo de cómo se construye la lista de argumentos y el nombre del método. ¡Y vea mi comentario en el código sobre la propiedad de objetos!
Desplazamiento rápido solo para asegurarse de que no se está preparando para una caída posterior: si realmente está obteniendo el hilo para imprimirlo, será mejor que obtenga la referencia del objeto y lo pase al PyObject_Print
. Por supuesto, tal vez esto es sólo para la ilustración, o si conoce mejor que yo lo que quiere hacer con los datos;)
char s[1024];
// How can I fill s, from obj.getName() ?
// Name of the method
static char method_name = "getName";
// No arguments? Score! We just need NULL here
char method_fmt_string = NULL;
PyObject *objname = PyObject_CallMethod(obj, obj_method, method_fmt_string);
// This is really important! What we have here now is a Python object with a newly
// incremented reference count! This means you own it, and are responsible for
// decrementing the ref count when you're done. See below.
// If there's a failure, we'll get NULL
if(objname == NULL)
{
// Again, this should just propagate the exception information
return NULL;
}
Ahora bien, hay un número de funciones en la sección String/Bytes Objects de los Concrete Objects Layer documentos; use el que sea mejor para usted.
Pero no se olvide este bit:
// Now that we're done with the object we obtained, decrement the reference count
Py_XDECREF(objname);
// You didn't mention whether you wanted to return a value from here, so let's just
// return the "None" singleton.
// Note: this macro includes the "return" statement!
Py_RETURN_NONE;
}
Nota el uso de Py_RETURN_NONE
allí, y nota que no es return Py_RETURN_NONE
!
PS. La estructura de este código está dictada en gran medida por el estilo personal (por ejemplo, retornos anticipados, cadenas de formato static char
dentro de la función, inicialización en NULL
). Esperemos que la información importante sea lo suficientemente clara aparte de las convenciones estilísticas.
Espera, ¿qué estás pasando en '_sayhello_obj'? ¿Es 'obj' (presumiblemente,' Hombre ("Juan") ')? O 'obj.getName()'? ¿O es 'obj' en la función C realmente' obj.getName() 'de la llamada de Python? – detly
Me disculpo. Tenía sueño cuando hice esta pregunta. obj era lo que quería pasar. obj.getName() fue copiado accidentalmente de mi experimento. Actualicé la pregunta. – Raymond
Bueno, porque esa es la pregunta que respondí! Lo sospechaba de todos modos. – detly