2015-06-22 12 views
9

Il problemaCython: lavorare con C++ flussi

Come si fa a utilizzare C++ flussi (come std::ifstream o ostream) da Cython? In C++, è possibile effettuare le seguenti operazioni:

std::ofstream output { filename, std::ios::binary }; 
output.write(...); 

Come si otterrebbe lo stesso in Cython?

Stato attuale

ho avvolto le strutture da fstream in Cython in modo che possa utilizzare i loro nomi nelle dichiarazioni di funzione, ma la parte difficile è quello di utilizzare (avvolgere in Cython, forse) il metodo di scrittura e per creare i flussi. Non ho trovato esempi di codice su internet.

P.S. So che una possibile risposta sarebbe semplicemente usare l'IO di Python, ma ho bisogno di passare/restituire gli stream da e verso il codice C++ con cui sto interagendo.

Questo è il codice che avvolge le dichiarazioni del flusso:

cdef extern from "<iostream>" namespace "std": 
    cdef cppclass basic_istream[T]: 
     pass 

    cdef cppclass basic_ostream[T]: 
     pass 

    ctypedef basic_istream[char] istream 

    ctypedef basic_ostream[char] ostream 

risposta

4

Non c'è molto di particolarmente speciale per il C++ iostreams rispetto ad avvolgere qualsiasi altra classe C++. L'unico problema è stato ottenere l'accesso a std::ios_base::binary, cosa che ho fatto dicendo a Cython che std::ios_base era uno spazio dei nomi e non una classe.

# distutils: language = c++ 

cdef extern from "<iostream>" namespace "std": 
    cdef cppclass ostream: 
     ostream& write(const char*, int) except + 

# obviously std::ios_base isn't a namespace, but this lets 
# Cython generate the correct C++ code 
cdef extern from "<iostream>" namespace "std::ios_base": 
    cdef cppclass open_mode: 
     pass 
    cdef open_mode binary 
    # you can define other constants as needed 

cdef extern from "<fstream>" namespace "std": 
    cdef cppclass ofstream(ostream): 
     # constructors 
     ofstream(const char*) except + 
     ofstream(const char*, open_mode) except+ 

def test_ofstream(str s): 
    cdef ofstream* outputter 
    # use try ... finally to ensure destructor is called 
    outputter = new ofstream("output.txt",binary) 
    try: 
     outputter.write(s,len(s)) 
    finally: 
     del outputter 

L'altra cosa da aggiungere è che non ho preso la briga con il pieno gerarchia di classe su modelli - che potrebbe essere utile se si desidera anche i wchar varianti, ma è molto più facile da solo raccontare Cython sulle classi si stai usando veramente.