Accediendo cabecera C / números mágicos con banderas Cython
-
18-09-2019 - |
Pregunta
Algunas bibliotecas C estándar que desea tener acceso con Cython tienen un montón de banderas. Los documentos Cython afirman que debo replicar las partes de la cabecera que necesito. Lo cual está bien cuando se trata de las definiciones de funciones. Por lo general, se replican en todas partes, documentos incluidos. Pero ¿qué pasa con todos esos números mágicos?
Si quiero llamar mmap
, siempre se puede encontrar la definición de función y pegarlo en un archivo .pxd:
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
Pero llamar a que necesita un montón de banderas como PROT_READ
, MAP_ANONYMOUS
y así sucesivamente. Tengo por lo menos dos problemas con esto:
En primer lugar, es un trabajo molesto para cazar a exactamente donde se definen esos números. De hecho Prefiero escribir un archivo .c y printf los valores que necesito. ¿Hay mejor manera de encontrar el valor de una bandera dada, tal como PROT_READ
?
En segundo lugar, qué tan estable son estos números? Después de haber extraído todos los valores que necesito y les hardcoded en mi fuente Cython, ¿cuáles son las posibilidades de que la compilación en una plataforma diferente si ha cambiado alrededor de, digamos PROT_READ
y PROT_EXEC
?
Incluso si la respuesta es que no hay maneras buenas o adecuadas para hacerlo, me gustaría escucharlo. Siempre puedo aceptar que algo es engorroso, siempre y cuando sé que no estoy perdiendo algo.
Solución
Para utilizar estas constantes de Cython, usted no tiene que averiguar exactamente de dónde venían o lo que son más de lo que lo hace a partir de C. Por ejemplo, el archivo de .pxd se parecen a
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
...
Mientras que las definiciones son (directa o indirectamente) incluidos desde foo.h, esto debería funcionar bien.
Otros consejos
Hay varias alternativas posibles:
- Utilice las banderas del pitón
mmap
módulo.- sencilla
- Enlaces de Python sólo funciona cuando hay existentes
- Utilice el objeto
mmap
Python, en primer lugar, y se la entrega a su código Cython- openening aún más simple
- podría tener algo de sobrecarga Python
- Utilice el generador de código de
ctypeslib
- algunos documentos sobre cómo extraer constantes
- Necesidades gccxml
- Sólo tienes que copiar los números.
Una vez dicho esto, los números son muy, muy estable. Si hubieran cambian, todos y cada programa en C usando mmap tendría que volver a compilar, como las banderas de las cabeceras están contenidas en el binario.
editar : mmap
es parte de POSIX , pero una lectura superficial no ha revelado si las banderas tienen que tener el mismo valor en todas las plataformas.
Escribir un archivo con este foo.c como el contenido:
#include <sys/mman.h>
A continuación, ejecute
cpp -dM foo.c | grep -v __ | awk '{if ($3) print $2, "=", $3}' > mman.py
lo que creará un archivo de Python que define todas las constantes de mman.h
Obviamente, se puede hacer eso por múltiple incluye si lo desea.
El archivo resultante puede ser que necesite un poco de limpieza, sino que va a conseguir cerrar.