Ctypes
Un article de Haypo.
Retour aux langages de programmation
ctypes est une bibliothèque Python permettant d'accéder aux fonctions et symboles d'une bibliothèque externe (en particulier, codée en C).
Sommaire |
Hello World!
Appel simple à printf de la libc :
$ python >>> from ctypes import cdll >>> libc=cdll.LoadLibrary('libc.so.6') >>> libc.printf("Hello World!\n") Hello World! 13
Définition du prototype (arguments et type de retour), exemple avec sqrt() de la bibliothèque mathématique :
$ python >>> from ctypes import cdll, c_double >>> libm = cdll.LoadLibrary('libm.so') >>> sqrt = libm.sqrt >>> sqrt.argtypes = (c_double,) >>> sqrt.restype = c_double >>> sqrt(4) 2.0
Types
Entiers
- c_byte, c_ubyte
- c_short, c_ushort
- c_int, c_uint
- c_long, c_ulong
- c_longlong, c_ulonglong (n'existe pas toujours)
La taille des différents types dépendent du système d'exploitation et du processeur.
Caractère
- c_char * équivalent du type C « char »
- c_char_p : équivalent du type C « char* »
- voir aussi create_string_buffer() (lire la section dédiée)
Pointeur
- c_char_p : char*
- c_void_p : void*
- POINTER(type) : type*
- Exemple : POINTER(c_int) : int*
On peut lire va valeur pointée avec « data.content » ou par son index : « data[0] » , « data[1] », ...
Pour définir une structure
from ctypes import Structure, Union, c_ulong, c_int, c_ushort class user_regs_struct(Structure): _fields_ = ( ("ebx", c_ulong), ("ecx", c_ulong), ("edx", c_ulong), ("esi", c_ulong), ... ) _sifields_t = (...) class siginfo(Union): _fields_ = ( ("as_int", c_int), ("as_short", c_short), ... )
On peut utiliser « _anonymous_ = ("_a", "_b", ...) » pour définir des champs anonymes dans une union.
Tableau d'octet (char*)
create_string_buffer(str) crée un tableau d'octets pouvant contenir des octets nuls :
from ctypes import create_string_buffer python_string = "string with \0 byte" c_string = create_string_buffer(python_string) assert c_string.value == 'string with ' assert c_string.raw == python_string
create_string_buffer(int) crée un tampon de N octet pouvant contenir de octets nuls :
>>> from ctypes import create_string_buffer >>> buffer = create_string_buffer(5) >>> buffer.raw '\x00\x00\x00\x00\x00'
c_char_p tronque au premier octet nul :
from ctypes import create_string_buffer python_string = "string with \0 byte" c_string = c_char_p(python_string) assert c_string.value == 'string with '
Modules
- ctypes_errno.py : lire la variable errno, code d'erreur C
- ctypes_libc.py : accéder à la libc de manière portable
- ctypes_stdint.py : types uint8_t, int32_t, ..., uint64_t
- ctypes_tools.py : outils divers
Outils connexes :
- cpu_info.py : informations sur le processeur
- os_tools.py : informations sur le système d'exploitation
Articles connexes
Liens externes
- Documentation officielle de ctypes
- pynetfilter_conntrack : binding Python de la bibliothèque libnetfilter_conntrack (pilotage du parefeu Linux)
- Ptrace : binding Python de la bibliothèque ptrace (débogueur de processus dans le noyau)
- ctypes_inet.py : Ancien script de test ctypes, fonctions "inet" de la libc