2010-02-05 5 views
4

Certaines bibliothèques C standard auxquelles je veux accéder avec Cython ont une tonne de drapeaux. Les documents Cython indiquent que je dois répliquer les parties de l'en-tête dont j'ai besoin. Ce qui est bien quand il s'agit de définitions de fonctions. Ils sont généralement reproduits partout, docs inclus. Mais qu'en est-il de tous ces nombres magiques?Accès aux nombres/drapeaux magiques d'en-tête C avec Cython

Si je veux appeler mmap, je peux toujours trouver la définition de la fonction et le coller dans un fichier .pxd:

void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) 

Mais l'appelant a besoin d'une tonne de drapeaux comme PROT_READ, MAP_ANONYMOUS et ainsi de suite. J'ai au moins deux problèmes avec ceci:

Premièrement, c'est un travail ennuyeux de traquer exactement où ces nombres sont définis. En fait, je préfère écrire un fichier .c et imprimer les valeurs dont j'ai besoin. Existe-t-il un meilleur moyen de trouver la valeur d'un drapeau donné tel que PROT_READ?

Deuxièmement, dans quelle mesure ces chiffres sont-ils stables? Après avoir extrait toutes les valeurs dont j'ai besoin et les avoir codées en dur dans ma source Cython, quelles sont les chances que la compilation sur une plate-forme différente ait changé, disons PROT_READ et PROT_EXEC?

Même si la réponse est qu'il n'y a pas de bonnes ou de bonnes façons de le faire, j'aimerais l'entendre. Je peux toujours accepter que quelque chose soit lourd tant que je sais que je ne manque pas quelque chose.

Répondre

6

Pour utiliser ces constantes de Cython, vous n'avez pas besoin de comprendre exactement d'où ils venaient ou ce qu'ils sont plus que vous faites de C. Par exemple, votre fichier .pxd peut ressembler à

cdef extern from "foo.h": 
    void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) 
    cdef int PROT_READ 
    cdef int MAP_ANONYMOUS 
    ... 

Tant que les définitions sont (directement ou indirectement) incluses dans foo.h, cela devrait fonctionner correctement.

1

Il existe plusieurs alternatives possibles:

  1. Les drapeaux du module Python mmap.
    • simples
    • ne fonctionne que quand il y a des liaisons existantes Python
  2. Utilisez l'objet Python mmap en premier lieu, et le remettre à votre code Cython
    • encore plus simple de openening
    • peut avoir un en-tête Python
  3. Utilisez le générateur de code de ctypeslib
    • some docs sur la façon d'extraire des constantes
    • besoins gccxml
  4. Il suffit de copier les chiffres.

Cela étant dit, les nombres sont très, très stables. Si elles changeaient, chaque programme C utilisant mmap devrait être recompilé, car les drapeaux des en-têtes sont contenus dans le binaire.

EDIT: mmap est part of POSIX, mais une lecture superficielle n'a pas révélé si les drapeaux doivent être la même valeur sur toutes les plateformes.

+1

La situation de portabilité est mauvaise: certaines valeurs sont définies par POSIX, d'autres non. Les POSIX sont à peu près corrigés, les autres peuvent varier d'une plateforme à l'autre. –

1

Écrire un fichier truc.c ce que le contenu:

#include <sys/mman.h> 

Lancez ensuite

cpp -dM foo.c | grep -v __ | awk '{if ($3) print $2, "=", $3}' > mman.py 

qui va créer un fichier python qui définit toutes les constantes de mman.h

De toute évidence, vous pouvez le faire pour plusieurs inclut si vous voulez.

Le fichier résultant peut nécessiter un peu de nettoyage, mais il vous permettra de le fermer.