2012-07-28 8 views
19

ho trovato risposte parziali tra la documentazione, mailing list, e this question here, ma volevo ottenere una risposta più diretta affrontare le mie specifiche ...struttura del progetto per il confezionamento di molte classi C++ in Cython ad un singolo oggetto condiviso

Sto imparando il cython cercando di avvolgere piccole parti, a poco a poco, di una libreria che sto già usando che è attualmente inclusa in boost :: python. Ho contribuito un po 'a questo boost wrapper e lo sto usando come riferimento C++, mentre allo stesso tempo sto usando ZeroMQ Python bindings come riferimento cython.

La mia domanda riguarda la struttura del progetto. La versione di potenziamento corrente di questo lib compila in un singolo .so, e questo è il mio obiettivo. Ho scoperto rapidamente che non è possibile compilare direttamente più moduli .pyx su un singolo .so. Ho quindi iniziato a definire la strada per definire i file pxd e le corrispondenti classi di implementazione esportate da python in .pxi e stavo cercando di includerli in un singolo pyx per la compilazione. Mentre funzionava inizialmente, una volta che ho scritto un po 'di più, ho riscontrato problemi con definizioni multiple in conflitto a causa del fatto che lo pxi include in luoghi diversi.

Mi piacerebbe sentire un approccio organizzativo adeguato che affronta le seguenti domande e gli obiettivi:

  • nominare le classi pubbliche lo stesso del cppclass (che sto facendo adesso avendo la cppclass in un diverso nome pyd e utilizzando lo spazio dei nomi importati per gestire i nomi simili, ala Using cimport to resolve naming conflicts)
  • singolo .so come l'uscita compilato (acceptable approach?)
  • si usa il pyx multi-approccio includono nel principale pyx per quello solo, o dovrebbe che il principale pyx contenga qualcos'altro oltre a contenere semplicemente gli include?
  • Dove definire a livello centrale le costanti che verranno esportate in python?
  • C'è una struttura di cartelle preferita? In questo momento ho tutto in una grande directory src sotto il mio setup.py. Diventa difficile vedere così tanti file pxi, pxd, pyx.
  • pxi sono completamente inutili ora? In caso contrario, ho bisogno di usare un ifndef guard in stile cython per gestire le inclusioni multiple tra diversi moduli?
  • So che i collegamenti Python ZeroMQ creano più moduli e utilizzano l'approccio del pacchetto includendoli tramite __init__.py. E 'davvero l'approccio corretto con cython?

Per riferimento, il progetto che sto praticando per il re-wrap è PyOpenNI (openni). Lo schema utilizzato da questo progetto di potenziamento consiste nel raccogliere gli oggetti comuni in un unico punto e quindi definire una definizione di intestazione 1-a-1 con l'origine, quindi un enorme wrapper che raccoglie tutte le definizioni nella singola posizione. E anche la gestione delle eccezioni e le utility personalizzate.

risposta

20

In attesa di una risposta definitiva, ho continuato a giocare con l'organizzazione del mio codice. L'inclusione dei file pyx in un singolo pyx per la compilazione ha funzionato finora.

mio setup.py è semplice come:

ext_modules = [ 
    Extension(
     "openni", 
     ["src/openni.pyx"], 
     language="c++", 
     include_dirs=['src/', '/usr/include/ni'], 
     libraries=['OpenNI'], 
    ) 
], 

Il principale openni.pyx assomiglia:

include "constants.pyx" 
include "exceptions.pyx" 
include "context.pyx" 
... 

Ho un comune libopenni.pxd per fornire la dichiarazione di solo persone esterne al resto dei moduli.

Nomino mia cppclass dichiarazioni un diverso pxd nome rispetto alle definizioni pyx classe per evitare la collisione nome:

xncontext.pxd

cdef extern from "XnCppWrapper.h" namespace "xn": 
    cdef cppclass Context: 
      ... 

context.pyx:

from libopenni cimport * 
from xncontext cimport Context as c_Context 

cdef class Context: 
    cdef c_Context *handle 
     ... 
+0

Puoi indicare il resto del codice che hai creato per questo wrapper? Sto incontrando un problema simile con una risoluzione simile. Non è bello ma funziona. – ibell

+2

Ehi. Quindi questo non era niente che finisse in un repo pubblico. La maggior parte dei miei ultimi esempi di questa struttura non sono online, ma qui ce n'è una che ho seguito poco dopo: https: //github.com/chadmv/plow/tree/master/lib/python/src – jdi

+2

Quello che faccio ora è mantenere i file pxi e includere la sottodirectory per renderla pulita. E ho solo il singolo pyx principale sopra di esso insieme al pxd che contiene tutte le dichiarazioni extern per il binding al C/CPP – jdi

0

Answeri ng Esiste una struttura di cartelle preferita?

Sì, la struttura delle cartelle preferito per i file di Cython .pyx e .pxd è di trattarli esattamente come si farebbe con i tuoi .py file: uno per ogni modulo, in una struttura del pacchetto ben organizzato. I file __init__.pxd possono essere forniti come i file __init__.py per assemblare una serie di simboli curati per raccogliere un set di simboli curati dai suoi sottomoduli/pacchetti per cimportare.

È vero, questo produce un file .so per modulo, ma questi file sono nascosti nella directory di creazione. Lo stesso vale per i moduli costruiti da Python; ci sono i corrispondenti file .so per ognuno di questi. È un problema?

+0

Come di recente mi sono convertito in un approccio multi-modo e importandoli in un singolo namespace tramite __init__. py – jdi

+0

Non ero a conoscenza del fatto che un __init __. pxd avesse importanza st il livello del modulo – jdi

+0

. I file .so separati per ogni modulo potrebbero essere un problema se si applica una licenza (protezione) a quei file .so quando la licenza richiede del tempo per inizializzarsi . –

Problemi correlati