Cette page présente un petit exemple de liaison entre Python et une librairie dynamique en C. L'exemple choisi ici est l'implémentation d'un appel depuis Python à la fonction `iconv` de la librairie C. (!) Documentation utilisée : http://docs.python.org/library/ctypes.html Fichier `/usr/local/lib/python2.5/site-packages/iconv.py` : {{{#!python #!/usr/bin/env python # -*- coding: utf-8 -*- """ Module de support iconv pour Python. Copyright : Agence universitaire de la Francophonie Licence : GNU General Public Licence, version 2 Auteur : Jean Christophe André Date de création : 20 mars 2009 """ from ctypes import * from ctypes.util import find_library # on n'exporte que la fonction iconv ('a marche pô ?!) __all__ = ["iconv"] # la librairie C _libc = CDLL(find_library("c")) # un type spécifique à iconv (pour stoquer l'état de son automate) _iconv_t = c_void_p # prototype de la fonction iconv_open(3) _iconv_open = _libc.iconv_open _iconv_open.argtypes = [c_char_p, c_char_p] _iconv_open.restype = _iconv_t # prototype de la fonction iconv(3) _iconv = _libc.iconv _iconv.argtypes = [_iconv_t, POINTER(POINTER(ARRAY(c_char, 1024))), POINTER(c_size_t), POINTER(POINTER(ARRAY(c_char, 4096))), POINTER(c_size_t)] _iconv.restype = c_size_t # prototype de la fonction iconv_close(3) _iconv_close = _libc.iconv_close _iconv_close.argtypes = [_iconv_t] _iconv_close.restype = c_int def iconv(from_code, to_code, string): """ from_code : encodage d'origine de string to_code : encodage souhaité en retour string : la chaîne dont il faut convertir l'encodage On pourra utiliser to_code='ascii//TRANSLIT' pour supprimer les accents. Attention : ça ne fonctionne pas à 100% avec les langues hors Latin-{N} ! Plus de détails dans la page de manuel de iconv(1). """ # on commence par créer un contexte de conversion cp = _iconv_open(c_char_p(to_code), c_char_p(from_code)) # on prépare les structures de données à transmettres inbuf = create_string_buffer(string, 1024) inbytesleft = c_size_t(len(inbuf)) p_inbuf = pointer(inbuf) outbuf = create_string_buffer(4096) outbytesleft = c_size_t(len(outbuf)) p_outbuf = pointer(outbuf) # on effectue la conversion _iconv(cp, byref(p_inbuf), byref(inbytesleft), byref(p_outbuf), byref(outbytesleft)) result = outbuf.value[:outbytesleft.value] # on détruit le contexte de conversion et on retourne le résultat _iconv_close(cp) return result if __name__ == "__main__": # on précise la translitération via un environnement linguistique from locale import setlocale, LC_ALL setlocale(LC_ALL, 'en_US.UTF-8') # test de cas limites (en français, vietnamien et japonais) from unicodedata import normalize t = u"fête cœur français tiếng việt đường プログフ" i = iconv("utf-8", "ascii//TRANSLIT", t.encode('utf-8')) u = normalize("NFKD", t).encode('ascii','ignore') print u"TEST: texte original: '%s'" % t print u"TEST: iconv(utf8..ascii//TRANSLIT): '%s'" % i print u"TEST: normalize(NFKD).encode(ascii,ignore): '%s'" % u }}} Lancement d'un test : {{{ python /usr/local/lib/python2.5/site-packages/iconv.py }}} Résultat sur Ubuntu "Intrepid" 8.10 : {{{ $ python iconv.py TEST: texte original: 'fête cœur français tiếng việt đường プログフ' TEST: iconv(utf8..ascii//TRANSLIT): 'fete coeur francais tieng viet ?uong ????' TEST: normalize(NFKD).encode(ascii,ignore): 'fete cur francais tieng viet uong ' }}} Exemple d'utilisation dans un programme : {{{#!python #!/usr/bin/env python # -*- coding: utf-8 -*- from iconv import iconv from locale import setlocale,LC_ALL setlocale(LC_ALL, 'fr_FR.UTF-8') texte_utf8 = u"fête cœur français".encode("utf-8") texte_sans_accent = iconv("utf-8", "ascii//TRANSLIT", texte_utf8) print u"Texte d'origine :", texte_utf8 print u"Suppression des accents :", texte_sans_accent }}}