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
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