2015-10-03 7 views
1

Я пытаюсь использовать SWIG для создания оболочки Go для C++ API, который использует std::istream для чтения двоичных данных. Я хотел бы иметь возможность передавать io.Reader этим API, но я не уверен, как создать сопоставление между ним и std::istream. Я знаю, что мне нужно реализовать подкласс std::streambuf, и я предполагаю, что остальные будут включать в себя режиссеров и типов, но я недостаточно знаком с SWIG, чтобы понять правильную комбинацию.Как преобразовать io.Reader в std :: istream с помощью SWIG & CGO?

Любые идеи?

+0

ли вы когда-нибудь найти решение для этого? – Sly

+0

Нет, еще нет. Сожалею! –

ответ

0

io.Reader является слишком общим, чтобы быть переданы функции C - это не может быть подкреплена на реальный файл на все (это просто класс, который реализует Read (...) функция)

Что вы могли бы do (до тех пор, пока вы не на окнах) используется os.Pipe(), чтобы дать вам объект FH, но, к сожалению, поток std :: * в запасе не имеет никакого способа создать поток из дескриптора открытого файла.

Битовая труба выглядит примерно так:

func wrapReader(r io.Reader) uintptr { 
    pr, pw, err := os.Pipe() 
    if err != nil { 
     panic(err) 
    } 

    go func() { 
     _, _ io.Copy(pw, r) 
     _ = pw.Close() 
    }() 

    return pr 
} 

Если вы объедините, что часть кода в этом ответе How to construct a c++ fstream from a POSIX file descriptor? вы можете получить то, что вам нужно

+0

'std :: istream' - это просто абстракция над потоком байтов типа' io.Reader'. Только реализация 'std :: ifstream' фактически имеет дело с файлами. –

+0

Правда, правда. Это больше работает, но, возможно, возможно, тогда написать адаптер, который перезвонит, чтобы перейти к чтению из io.Reader. Получение GC права так, чтобы читатель не разрушался под вами, где большая часть работы может быть тогда. –

+0

Ну, поскольку Go не разрешает указателям Go передавать код C, обычным решением является сохранение объекта на карте и передача ключа назад и вперед. Объект не будет GC'd, пока он не будет удален с карты. Мой вопрос заключается не столько в том, как сделать 'std :: streambuf', сколько в том, чтобы заставить SWIG использовать эту реализацию всякий раз, когда он сталкивается с C++ API, который принимает' std :: istream'. –