2014-04-29 12 views
5

Ho una libreria C:Python - ctypes - Come chiamare funzioni e accedere ai campi struct?

smart_string.h:

typedef struct SmartString { 
    unsigned string_len; 
    unsigned alloc_len; 
    char *str; 
    char *str_terminator; 

} SmartString; 

SmartString *SmartString_new(char *str); 
... definitions of more functions ... 

L'implementazione si trova in un file chiamato smart_string.c.

Ho bisogno di una guida per eseguire la funzione SmartString_new() e accedere ai campi del struct-pointer restituito.

Qualcuno può, per favore, mostrarmi come si fa?

Grazie!

risposta

8

Rispondere a me stesso e condividere la conoscenza con voi:

In primo luogo, hanno bisogno di creare una libreria condivisa dal file C:

gcc -shared -fpic smart_string.c -o SmartString.so

Quindi, utilizzare il seguente codice Python (vedi commenti per spiegazione su ogni azione fatto):

Nota: char*, come appare nelle API di cui sopra è una stringa modificabile C, mentre const char* è una stringa di sola lettura. Poiché l'API C richiede char* e non const char*, dobbiamo passare ad esso una stringa mutabile, in modo che possa essere modificata dal codice C. Le stringhe Python sono immutable per impostazione predefinita. Qui usiamo di conseguenza, la funzione di create_string_buffer()

python_smart_string.py:

import ctypes 
from ctypes import * 

# Defining the python type that represents the C SmartString 
# It must extend the 'Structure' class 
# Structure, c_uint, c_char_p, etc. were imported from ctypes 
class SmartString(Structure): 
    _fields_=[("string_len",c_uint), 
       ("alloc_len",c_uint), 
       ("str",c_char_p), 
       ("str_terminator", c_char_p)] 


# Loading the C shared lib I've just compiled 
smartstring_lib = ctypes.CDLL('SmartString.so') 

# Defining pointer to the SmartString_new() function 
SmartString_new = smartstring_lib.SmartString_new 

# Declaring the function return type - a pointer to a SmartString object - just like in the C code 
SmartString_new.restype = POINTER(SmartString) 

# Declaring list of parameter types. In this case, the list contains only one item, 
# as the function has only one parameter 
SmartString_new.argtypes = [c_char_p] 

# Calling the SmartString_new() function. Expecting to get a pointer to SmartString object into 'my_str' 
# The API requires a MUTABLE string, so create_string_buffer() is used here 
# The reference to this string is not saved, as I don't care if it is modified by the C code 
my_str = SmartString_new(create_string_buffer('my nice string')) 

# Printing fields of the dereferenced returned value (dereferencing is done using '.contents') 
print my_str.contents.string_len 
print my_str.contents.alloc_len 
print my_str.contents.str 
print my_str.contents.str_terminator 
+2

specificare 'SmartString_new.argtypes = [c_char_p]'. Potrebbe essere necessario mantenere un riferimento a 'create_string_buffer()'. 'my_str [0]' è un altro modo per dereferenziare un puntatore. – jfs

Problemi correlati