Domanda

Alcune librerie C standard che voglio accedere con Cython hanno un sacco di bandiere. La documentazione Cython affermano che devo replicare i parti dell'intestazione ho bisogno. Che va bene quando si tratta di definizioni di funzioni. Di solito sono replicati ovunque, documenti compresi. Ma che dire di tutti quei numeri magici?

Se voglio chiamare mmap, posso sempre trovare la definizione di funzione e incollarlo in un file .pxd:

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

Ma chiamando ha bisogno di un sacco di bandiere come PROT_READ, MAP_ANONYMOUS e così via. Ho almeno due problemi con questo:

In primo luogo, è un lavoro fastidioso per dare la caccia esattamente dove sono definiti quei numeri. In realtà preferirei scrivere un file .c e printf i valori di cui ho bisogno. Ci sono un modo migliore di trovare il valore di un determinato bandiera come PROT_READ?

In secondo luogo, come stabili sono questi numeri? Dopo aver estratto tutti i valori di cui ho bisogno e li hardcoded nella mia fonte Cython, quali sono le probabilità che la compilazione su una piattaforma diversa è commutata in giro, diciamo PROT_READ e PROT_EXEC?

Anche se la risposta è che non ci sono modi buoni o corretto di farlo, mi piacerebbe sentirla. Posso sempre accettare che qualcosa è ingombrante finché so che non mi manca qualcosa.

È stato utile?

Soluzione

Per usare queste costanti da Cython, non è necessario capire esattamente da dove venivano o quello che sono più di quanto si fa da C. Ad esempio, il file .pxd può apparire come

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
    ...

Fino a quando le definizioni sono (direttamente o indirettamente) incluso nel periodo dal foo.h, questo dovrebbe funzionare bene.

Altri suggerimenti

Ci sono diverse alternative possibili:

  1. Utilizzare le bandiere dal Python mmap modulo.
    • semplice
    • solo funziona quando ci sono già esistenti binding Python
  2. Utilizzare l'oggetto mmap Python, in primo luogo, e consegnarlo al codice Cython
    • ancora più semplice openening
    • potrebbe avere un certo overhead Python
  3. Utilizza il generatore di codice di ctypeslib
  4. Basta copiare i numeri.

Detto questo, i numeri sono molto, molto stabile. Se avessero cambiano, ogni programma C utilizzando mmap dovrebbe essere ricompilato, come le bandiere delle intestazioni sono contenuti nel binario.

Modifica : mmap è parte di POSIX , ma una lettura superficiale non ha rivelato se le bandiere devono essere lo stesso valore su tutte le piattaforme.

Scrivi una foo.c file con questo come il contenuto:

#include <sys/mman.h>

Quindi eseguire

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

che creerà un file python che definisce tutte le costanti da mman.h

Ovviamente, si può fare per il multiplo comprende se si desidera.

Il file risultante potrebbe essere necessario un po 'di pulizia, ma si otterrà si chiude.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top