Per estrarre un argomento da un'invocazione del metodo, è necessario guardare le funzioni documentate in Parsing arguments and building values, come PyArg_ParseTuple
. (Questo è per se stai solo argomentando posizionale! Ce ne sono altri per argomenti di positional-and-keyword, ecc.)
L'oggetto che torni da PyArg_ParseTuple
non ha il numero di riferimenti aumentato. Per semplici funzioni C, probabilmente non devi preoccuparti di questo. Se stai interagendo con altre funzioni Python/C, o se stai rilasciando il lock dell'interprete globale (cioè consentendo il threading), devi pensare molto attentamente alla proprietà dell'oggetto.
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.
Per chiamare un metodo su un oggetto, è necessario utilizzare uno o PyObject_CallMethod
PyObject_CallMethodObjArgs
, a seconda di come si costruisce la lista degli argomenti e il nome del metodo. E vedi il mio commento nel codice sulla proprietà dell'oggetto!
Breve digressione solo per assicurarsi che non ti stai preparando per un autunno più tardi: se ti stai solo strappando la stringa per stamparlo, è meglio ottenere il riferimento dell'oggetto e passarlo a PyObject_Print
. Certo, forse questo è solo per l'illustrazione, o se si sa meglio di me che cosa si vuole fare con i dati;)
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;
}
Ora ci sono una serie di funzioni nella sezione String/Bytes Objects dei Concrete Objects Layer documenti; usa quello che funziona meglio per te.
Ma non dimenticare questo 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 l'uso di Py_RETURN_NONE
lì, e nota che non è return Py_RETURN_NONE
!
PS. La struttura di questo codice è dettata in gran parte dallo stile personale (ad esempio, i resi anticipati, le stringhe di formato static char
all'interno della funzione, l'inizializzazione su NULL
). Speriamo che le informazioni importanti siano abbastanza chiare a parte le convenzioni stilistiche.
Aspetta, cosa stai passando a '_sayhello_obj'? E ''obj' (presumibilmente,' Man ("John") ')? O 'obj.getName()'? O è 'obj' nella funzione C in realtà' obj.getName() 'dalla chiamata Python? – detly
Mi scuso. Ero addormentato quando ho fatto questa domanda. obj era ciò che volevo passare. obj.getName() è stato accidentalmente copiato dal mio esperimento. Ho aggiornato la domanda. – Raymond
Bene, perché questa è la domanda che ho risposto! Lo sospettavo comunque. – detly