import ctypes malib = ctypes.CDLL("./target/release/libpy.so") # définition de classe (en réalité d'une structure) class Bidule(ctypes.Structure): _fields_ = [ ("i", ctypes.c_int) ] # mise en oeuvre des wrappers pour la fonction envoyée à Rust # ainsi que la fonction qui va gérer l'exécution côté Rust rappel_type = ctypes.CFUNCTYPE( ctypes.c_int, ctypes.POINTER( Bidule ) ) def recevoir( obj_type ): def _sup_fct( fct ): @rappel_type # un décorateur dans un autre, c'est possible ! def _fct( adresse ): # ici je reçois le pointeur que Rust a reçu objet = ctypes.cast( adresse, ctypes.POINTER( obj_type ) )[0] return fct( objet ) return _fct return _sup_fct executer_rust = malib.executer executer_rust.argtypes = [ ctypes.POINTER( Bidule ),] executer_rust.restype = ctypes.c_int; # cette fonction sera exécutée "côté Rust" @recevoir( Bidule ) def tester( objet ): if objet.i > 10: objet.i = 0 return 1 else: return 0 # le reste... fct_afficher = malib.afficher fct_afficher.argtypes = [ ctypes.c_char_p, ctypes.POINTER( Bidule ) ] fct_afficher.restype = ctypes.c_int; b = Bidule( i = 42 ) executer_rust( b, tester ) # 'i' va passer à 0 car i > 10 r = fct_afficher( "bonjour - éèà".encode( "utf-8" ), b ) print("le retour est :", r) print("Bidule.i =", b.i)