números mágicas Aceder cabeçalho C / bandeiras com Cython
-
18-09-2019 - |
Pergunta
Algumas bibliotecas C padrão que deseja acessar com Cython tem uma tonelada de bandeiras. Estado do Cython docs que eu deve replicar as partes da necessidade de cabeçalho eu. O que é bom quando se trata de funções definições. Eles normalmente são replicadas em todos os lugares, docs incluído. Mas o que dizer de todos aqueles números mágicos?
Se eu quiser chamar mmap
, eu sempre pode encontrar a definição da função e colá-lo em um arquivo .pxd:
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
Mas chamar ele precisa de uma tonelada de bandeiras como PROT_READ
, MAP_ANONYMOUS
e assim por diante. Eu tenho pelo menos dois problemas com isso:
Em primeiro lugar, é um trabalho chato para caçar exatamente onde esses números são definidos. Na verdade eu prefiro escrever um arquivo .c e printf os valores que eu preciso. Há alguma maneira melhor de encontrar o valor de uma determinada bandeira como PROT_READ
?
Em segundo lugar, quão estável são esses números? Tendo extraído todos os valores que eu preciso e codificado-los em minha fonte Cython, quais são as chances de que a compilação em uma plataforma diferente mudou em torno de, digamos PROT_READ
e PROT_EXEC
?
Mesmo que a resposta é que não há bom ou formas adequadas de fazer isso, eu gostaria de ouvi-lo. Eu sempre pode aceitar que algo é complicado, desde que eu sei que não estou faltando alguma coisa.
Solução
Para usar essas constantes de Cython, você não precisa descobrir exatamente de onde vieram ou o que eles são mais do que você faz de C. Por exemplo, seu arquivo .pxd pode parecer
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
...
Enquanto as definições são (direta ou indiretamente) incluídas a partir de foo.h, isso deve funcionar bem.
Outras dicas
Existem várias alternativas possíveis:
- Use as bandeiras do Python
mmap
módulo.- simples
- só funciona quando há existente ligações Python
- Use o objeto Python
mmap
em primeiro lugar, e entregá-lo ao seu código Cython- ainda mais simples openening
- pode ter alguma Python sobrecarga
- Use o gerador de código de
ctypeslib
- alguns docs sobre como extrair constantes
- necessidades gccxml
copiar - Apenas os números.
Dito isto, os números são muito, muito estável. Se eles mudam, cada programa em C usando mmap teria que ser recompilados, como as bandeiras dos cabeçalhos estão contidos no binário.
Editar : mmap
é parte de POSIX , mas uma leitura superficial não revelou se as bandeiras tem que ser o mesmo valor em todas as plataformas.
Escrever um arquivo foo.c com este como o conteúdo:
#include <sys/mman.h>
Em seguida, execute
cpp -dM foo.c | grep -v __ | awk '{if ($3) print $2, "=", $3}' > mman.py
que irá criar um arquivo de python que define todas as constantes de mman.h
Obviamente, você pode fazer isso por múltiplos inclui, se quiser.
O arquivo resultante pode precisar de um pouco de limpeza, mas vai chegar perto.