Ctypes

Un article de Haypo.

Retour à la page précédente 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

[modifier] 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

Pour les procédures, fonctions qui ne renvoient rien, utilisez « func.restype = None ».

[modifier] Types

[modifier] 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. Utilisez ctypes_stdint.py pour avoir des types de taille fixe.

[modifier] 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)

[modifier] 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] », ...

[modifier] sizeof()

La fonction sizeof(type) calcule la taille d'un type en octets.

[modifier] 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.

[modifier] 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 '

[modifier] Charger une bibliothèque

Exemple simple :

from ctypes import cdll
libm = cdll.LoadLibrary('libm.so')

Pour trouver une bilbiothèque, on peut utiliser :

from ctypes import cdll
from ctypes.util import find_library
LIBC_FILENAME = find_library('c')
libc = cdll.LoadLibrary(LIBC_FILENAME)

C'est la techhique utilisée par ctypes_libc.py pour charger bibliothèque C de façon portable (testé sour Linux, FreeBSD et Mac OS X).

[modifier] Modules

Outils connexes :

[modifier] Articles connexes

[modifier] Liens externes