5

Google が解決策を見つけられなかったことに非常に驚いています。SDL_RWops を std::istream で使用できるようにするソリューションを探しています。SDL_RWops は、SDL でデータを読み書きするための代替メカニズムです。

問題に取り組むサイトへのリンクはありますか?

明らかな解決策は、メモリに十分なデータを先読みしてから SDL_RWFromMem を使用することです。ただし、これには事前にファイルサイズを知る必要があるという欠点があります。

SDL_RWops関数を「オーバーライド」することで、問題を解決できるようです...

4

2 に答える 2

6

私は自分の質問に答えるのが悪いと感じていますが、しばらくの間私を夢中にさせていました。これが私が思いついた解決策です:

int istream_seek( struct SDL_RWops *context, int offset, int whence)
{
    std::istream* stream = (std::istream*) context->hidden.unknown.data1;

         if ( whence == SEEK_SET )
        stream->seekg ( offset, std::ios::beg );
    else if ( whence == SEEK_CUR )
        stream->seekg ( offset, std::ios::cur );
    else if ( whence == SEEK_END )
         stream->seekg ( offset, std::ios::end );

    return stream->fail() ? -1 : stream->tellg();
}


int istream_read(SDL_RWops *context, void *ptr, int size, int maxnum)
{
    if ( size == 0 ) return -1;
    std::istream* stream = (std::istream*) context->hidden.unknown.data1;
    stream->read( (char*)ptr, size * maxnum );

    return stream->bad() ? -1 : stream->gcount() / size;
}

int istream_close( SDL_RWops *context )
{
    if ( context ) {
        SDL_FreeRW( context );
    }
    return 0;
}


SDL_RWops *SDL_RWFromIStream( std::istream& stream )
{
    SDL_RWops *rwops;
    rwops = SDL_AllocRW();

    if ( rwops != NULL ) 
    {
        rwops->seek = istream_seek;
        rwops->read = istream_read;
        rwops->write = NULL;
        rwops->close = istream_close;
        rwops->hidden.unknown.data1 = &stream;
    }
    return rwops;
}

istream が SDL によって決して解放されない (そして、それらが操作を通じて存続する) という前提の下で機能します。また、istream サポートのみが含まれており、ostream に対して別の関数が実行されます。iostream を渡すことができることはわかっていますが、istream を変換関数に渡すことはできません。

エラーやアップグレードに関するヒントは大歓迎です。

于 2010-01-13T16:57:19.807 に答える
1

istream から SDL_RWops 構造体を取得しようとしている場合は、istream 全体をメモリに読み込み、SDL_RWFromMem を使用してそれを表す構造体を取得します。

以下は簡単な例です。健全性チェックが行われないため、安全ではないことに注意してください。たとえば、ファイルのサイズが 0 の場合、buffer[0] にアクセスすると、例外がスローされるか、デバッグ ビルドでアサートされる可能性があります。

// Open a bitmap
std::ifstream bitmap("bitmap.bmp");

// Find the bitmap file's size
bitmap.seekg(0, std::ios_base::end);
std::istream::pos_tye fileSize = bitmap.tellg();
bitmap.seekg(0);

// Allocate a buffer to store the file in
std::vector<unsigned char> buffer(fileSize);

// Copy the istream into the buffer
std::copy(std::istreambuf_iterator<unsigned char>(bitmap), std::istreambuf_iterator<unsigned char>(), buffer.begin());

// Get an SDL_RWops struct for the file
SDL_RWops* rw = SDL_RWFromMem(&buffer[0], buffer.size());

// Do stuff with the SDL_RWops struct
于 2010-01-13T16:58:20.813 に答える