Ctypes

Un article de Haypo.

(Différences entre les versions)
Version du 20 février 2008 à 13:35 (modifier)
Haypo (Discuter | Contributions)

← Différence précédente
Version du 20 février 2008 à 13:38 (modifier) (défaire)
Haypo (Discuter | Contributions)
(Modules)
Différence suivante →
Ligne 98 : Ligne 98 :
c_string = '''c_char_p'''(python_string) c_string = '''c_char_p'''(python_string)
assert c_string.value == 'string with ' assert c_string.value == 'string with '
 +
 +== 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 '''[http://fusil.hachoir.org/trac/browser/ptrace/trunk/ptrace/ctypes_libc.py ctypes_libc.py]''' pour charger bibliothèque C de façon portable (testé sour Linux, FreeBSD et Mac OS X).
== Modules == == Modules ==
* '''[http://fusil.hachoir.org/trac/browser/ptrace/trunk/ptrace/ctypes_errno.py ctypes_errno.py]''' : lire la variable errno, code d'erreur C * '''[http://fusil.hachoir.org/trac/browser/ptrace/trunk/ptrace/ctypes_errno.py ctypes_errno.py]''' : lire la variable errno, code d'erreur C
-* '''[http://fusil.hachoir.org/trac/browser/ptrace/trunk/ptrace/ctypes_libc.py ctypes_libc.py]''' : accéder à la libc de manière portable 
* '''[http://fusil.hachoir.org/trac/browser/ptrace/trunk/ptrace/ctypes_tools.py ctypes_tools.py]''' : outils divers * '''[http://fusil.hachoir.org/trac/browser/ptrace/trunk/ptrace/ctypes_tools.py ctypes_tools.py]''' : outils divers

Version du 20 février 2008 à 13:38

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

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

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

sizeof()

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

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 '

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

Modules

Outils connexes :

Articles connexes

Liens externes