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.

Foi útil?

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:

  1. Use as bandeiras do Python mmap módulo.
    • simples
    • só funciona quando há existente ligações Python
  2. 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
  3. Use o gerador de código de ctypeslib
  4. copiar
  5. 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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top