2012-03-26 5 views
2

두 프레임 워크 (OpenSceneGraph 및 wxWidgets) 간의 메모리 내 이미지 변환을 수행하고 있습니다. 기본 클래스 (osg::ImagewxImage)에 관심 싶어하지, 내가 스트림 I를 지향 사용/O는 두 API가과 같이 제공 기능 :std :: vector를 기반으로 std :: stringbuf를 만듭니다. <char>

1)하여 만드는 std::stringstream

2)를 사용하여 스트림 OSG의 쓰기 작가는

3)이 상당히 잘 작동 wxWigdets 리더

를 사용하여 스트림에서 읽습니다. 지금까지는 스트림 버퍼에 대한 직접 액세스를 사용했지만 최근에는 std::stringstream의 "인접하지 않은 기본 버퍼"문제에주의를 기울였습니다. 버퍼에 const char* ptr을 가져 오기 위해 kludge를 사용했지만 MSVC 9 및 GCC 4.x를 사용하여 Windows, Linux 및 OSX에서 테스트 했으므로 해결되지 않았습니다.

이제이 코드는 시한 폭탄이며이를 제거하고 싶습니다. 이 문제는 SO (here for instance)에 여러 번 제기되었지만 실제로 작동 할 수있는 가장 단순한 작업을 수행하는 데 도움이되는 답을 찾을 수 없었습니다.

가장 합리적인 일은 장면 뒤에있는 벡터를 사용하여 내 자신의 streambuf를 만드는 것입니다. 이렇게하면 버퍼가 인접 해 있음을 보증 할 수 있습니다. 내가 알고이 일반적인 해결책이 아니다,하지만 내 제약 주어진 :

1) 필요한 크기는하지이 무한하고 실제로는 매우 예측

2) 내 스트림이 정말 std::iostream (I 할 필요가 입니다 원시 char 배열을 사용할 수 없음) API 때문에

누구나 내가 chars 벡터를 사용하여 맞춤 stringbuf를 어떻게 사용할 수 있는지 알고 있습니까? "std::stringstream::str()"이라고 대답하지 마십시오. 을 알고 있습니다.하지만 다른 것을 찾고 있습니다. (2-3 MB를 복사하는 것이 너무 빠르기 때문에 내가 알아 채지 못할 수도 있습니다. 차이점은, 나는 여전히 운동의 아름다움을 위해서 맞춤 stringbufs에 관심이 있다고 생각해 봅시다.)

답변

3

std::vector<char>를 사용 streambuf 자신을 만들 그냥 istream 또는 ostream (오히려 양방향 보다)를 사용할 수 있으며, 추구가 필요하지 않습니다, 그것은 아주 간단합니다 (코드의 약 10 라인)의 경우. 문자열이 매우 크지 않은 한, 왜 귀찮게합니까? C++ 11 표준 은 std::string이 연속적임을 보장합니다. char*&myString[0]으로 C 스타일 배열로 사용할 수 있습니다. 그리고 C++ 11이이 보증을 추가 한 이유는 기존의 연습을 인정한 것이 었습니다. 여기에는 사례가 없었던 구현이 전혀 없었습니다 (이제는 필수 항목이므로 앞으로는 이것이 적용되지 않습니다. 에 구현되지 않습니다).

+0

답을 잘 모르겠습니다. istream/ostream 만 사용 : 하나의 플러그인은 ostream을보고 다른 하나는 istream을 볼 필요가 있습니다. 어쩌면 나는 각각의 하나의 벡터를 사용하여 하나를 만들 수 있습니까? std :: string 사용에 관해서 : 좋습니다.하지만 문자열에서 스트림을 어떻게 생성합니까? – Tibo

+0

@ 하나의 플러그인은 ostream이 필요하고 다른 플러그인은 istream이 필요한 경우 양방향으로 만들어야 할 수도 있습니다. 또는 이들이 동시에 필요하지 않으면 ostream을 작성한 다음 istream을 작성하고 동일한 버퍼를 사용하십시오. 문자열 밖의 스트림에 대해서는 :'std :: [io] stringstream'이 이미 있습니다. –

+0

C++ 11에 따라 std :: stringstream의 버퍼가 연속적이라는 보장이 있습니까? 그리고 아무데도 std :: stringstreams std :: strings 내부적으로 - 모든 포인터를 읽을 수 있을까요? – Tibo

1

boost :: iostreams에는 몇 가지 준비가 완료된 싱크가 있습니다. 일종의 상한이 있고 청크를 미리 할당 할 수있는 경우에는 싱크가 동적으로 증가하지 않지만 다른 한편으로는 양수 일 수 있습니다. array_sink이 있습니다. back_inserter_device도 있는데, 이는보다 일반적인 것으로, 예를 들어 std::vector으로 곧장 작동합니다.back_inserter_device를 사용하는 예 :

#include <string> 
#include <iostream> 
#include "boost/iostreams/stream_buffer.hpp" 
#include "boost/iostreams/device/back_inserter.hpp" 
int main() 
{ 
    std::string destination; 
    destination.reserve(1024); 
    boost::iostreams::stream_buffer< boost::iostreams::back_insert_device<std::string> > outBuff((destination)); 
    std::streambuf* cur = std::cout.rdbuf(&outBuff); 
    std::cout << "Hello!" << std::endl; 
    // If we used array_sink we'd need to use tellp here to retrieve how much we've actually written, and don't forgot to flush if you don't end with an endl! 
    std::cout.rdbuf(cur); 
    std::cout << destination; 
} 
+0

감사합니다. 나는이 프로젝트에서 부스트를 사용하고 있지 않지만 미래의 것들을 위해 당신의 솔루션을 나의 베개 밑에 두도록하겠다. – Tibo

관련 문제