2015-05-21 25 views
5

Ecco il mio codice C, ne ho creato una condivisa. Quando carico la libreria condivisa in Python ed eseguo il codice Python di seguito, mi si blocca. Perché?Perché Python si blocca mentre restituisce una stringa C?

extern "C" { 
PyObject* foo2(char* b) 
{ 
    return Py_BuildValue("s", b); 
} 

} 

Ed ecco quello che sto facendo in Python:

from ctypes import * 
    d = cdll.LoadLibrary('./foo.so') 
    d.foo2.restype = c_char_p 
    v = d.foo2('hello world') 
    print pythonapi.PyString_Size(v) 

Se serve, io sono a python2.6.

+1

'c_char_p' - non significa' char * '? siete ** non ** restituisce un '' char * ... –

+1

perché stai usando 'ctypes' per aprire una libreria che utilizza l'API di Python, invece di fare quella biblioteca un modulo di estensione Python? – interjay

risposta

4

Si sta dicendo cdll che la funzione restituisce un char* ma in realtà restituisce un PyObject*. I due devono essere d'accordo.

9

Il tuo problema è che tu stia mentendo sul tipo di ritorno:

d.foo2.restype = c_char_p 

Il tipo di rendimento effettivo è PyObject *. Ma ctypes vedrà che c_char_p, trasmetterà il PyObject * a char * e quindi provi a convertire quello char * in una stringa con PyString_FromString, che leggerà chissà quali byte arbitrari finché non raggiunge un carattere NUL.

Il modo per specificare un PyObject * è con py_object.

Inoltre, probabilmente desidera impostare il argtype s. E questa volta, in realtà è un c_char_p:

d = cdll.LoadLibrary('./foo.so') 
d.foo2.argtypes = [c_char_p] 
d.foo2.restype = py_object 

Ma, come interjay sottolinea in un commento, è un po 'stupido per essere la costruzione di una libreria C che utilizza l'API di Python C e quindi chiamando via ctypes. Questo è occasionalmente, ma normalmente la soluzione è finire semplicemente costruendo un modulo di estensione C invece di fare l'80% del lavoro per nessuno dei vantaggi ...