C'è un libx.so
che esportano 2 funzioni, e un struct
,C struct in Python
typedef struct Tag {
int num;
char *name;
}Tag;
Tag *create(int n, char *n)
{
Tag *t = malloc(sizeof(Tag));
t->num = n;
t->name = n;
return t;
}
void use(Tag *t)
{
printf("%d, %s\n", t->num, t->name);
}
voglio chiamare create
in Python e quindi salvare il Tag *res
restituito da create
, poi chiamerò use
e passaggio il Tag *res
salvato prima di use
, qui è esso (solo per dimostrare):
>>>libx = ctypes.CDLL("./libx.so")
>>>res = libx.create(c_int(1), c_char_p("a"))
>>>libx.use(res)
il codice di cui sopra potrebbe essere sbagliato, proprio per dimostrare quello che voglio fare.
E il mio problema è che, come posso salvare il risultato restituito da create
? Perché restituisce un puntatore a un struct
definito dall'utente e non voglio costruire la controparte di struct Tag
in Python, sarebbe c_void_p
fare il trucco?
UPDATE
Da @ risposta di David, io ancora non capisco una cosa:
il puntatore (
c_char_p("a")
) è valido solo per la durata della chiamata acreate
. Appena creato restituisce quel puntatore non è più valido .
E assegno c_char_p("a")
a t->name
in create
, quando la chiamata al create
finiture, è t->name
un puntatore penzoloni? Perché secondo le parole citate, quel puntatore non è più valido dopo create
. Perché c_char_p("a")
non è più valido?
Sono appena andato puzzolente nei miei pantaloni –
Bene, signore, ci sono 3 cose che non capisco. 1, 'il puntatore alla memoria di quel tipo è valido solo per la durata della chiamata da creare. Perché è così? Presumo che sia perché dopo la chiamata a 'create',' c_char_p ("a") 'il conteggio di rif. Va a zero, quindi' "a" 'è garbage-collected, giusto? 2, nel tuo codice, 'res' è un oggetto' c_void_p', ma 'libx.use' prende un' Tag * 'arg, posso semplicemente passare' res' direttamente a 'libx.use' senza cast? 3, perché dovrei esplicitamente 'destroy (res)'? – Alcott
Ho appena eseguito un test, sembra che il mio codice possa funzionare correttamente, signore. – Alcott