2015-06-22 18 views
9

Vấn đềCython: làm việc với C++ suối

như thế nào c suối một sử dụng ++ (như std::ifstream hoặc ostream) từ Cython? Trong C++, bạn có thể làm như sau:

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

Bạn sẽ đạt được điều tương tự như thế nào trong Cython?

Thực trạng

Tôi đã bọc các cấu trúc từ fstream trong Cython vì vậy mà tôi có thể sử dụng tên của họ trong tờ khai chức năng, nhưng phần khó khăn là sử dụng (bọc trong Cython, có lẽ) phương pháp ghi và để tạo luồng. Tôi không tìm thấy bất kỳ ví dụ mã nào trên internet.

P.S. Tôi biết một câu trả lời có thể là chỉ cần sử dụng IO của Python nhưng tôi cần phải chuyển/trả về các luồng đến và từ mã C++ mà tôi đang giao tiếp với.

Đây là mã mà kết thúc tốt đẹp tờ khai dòng:

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 

Trả lời

4

Không có nhiều đặc biệt là đặc biệt về C++ iostreams so với gói bất kỳ ++ lớp C khác. Các bit khó khăn duy nhất đã được truy cập vào std::ios_base::binary, mà tôi đã làm bằng cách nói với Cython rằng std::ios_base là một không gian tên và không phải là một lớp học.

# 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 

Điều khác để thêm là tôi đã không làm phiền với các hệ thống cấp bậc lớp templated đầy đủ - có thể hữu ích nếu bạn cũng muốn wchar biến thể, nhưng nó dễ dàng hơn để chỉ nói Cython về lớp bạn đang thực sự sử dụng.