C++ 从std::istream读取SDL_rOps
我很惊讶谷歌没有找到解决方案。我正在寻找一种解决方案,允许SDL_RWops与std::istream一起使用。SDL_RWops是在SDL中读取/写入数据的替代机制 有解决这个问题的网站的链接吗 一个显而易见的解决方案是将足够的数据预读入内存,然后使用SDL_RWFromMem。但是,这样做的缺点是我需要事先知道文件大小C++ 从std::istream读取SDL_rOps,c++,sdl,istream,C++,Sdl,Istream,我很惊讶谷歌没有找到解决方案。我正在寻找一种解决方案,允许SDL_RWops与std::istream一起使用。SDL_RWops是在SDL中读取/写入数据的替代机制 有解决这个问题的网站的链接吗 一个显而易见的解决方案是将足够的数据预读入内存,然后使用SDL_RWFromMem。但是,这样做的缺点是我需要事先知道文件大小 似乎这个问题可以通过“覆盖”SDL_rOps函数来解决…我很抱歉回答我自己的问题,但这让我有一段时间都很紧张,这就是我提出的解决方案: int istream_seek( s
似乎这个问题可以通过“覆盖”SDL_rOps函数来解决…我很抱歉回答我自己的问题,但这让我有一段时间都很紧张,这就是我提出的解决方案:
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传递给转换函数:/
欢迎提供有关错误或升级的任何提示。如果您试图从istream获取SDL\u RWops结构,可以通过将整个istream读入内存,然后使用SDL\u rFromMem获取一个结构来表示它 下面是一个简单的例子;请注意,这是不安全的,因为没有进行健康检查。例如,如果文件大小为0,则访问缓冲区[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
//打开位图
std::ifstream位图(“bitmap.bmp”);
//查找位图文件的大小
bitmap.seekg(0,std::ios\u base::end);
std::istream::pos_tye fileSize=bitmap.tellg();
位图。seekg(0);
//分配一个缓冲区来存储文件
向量缓冲区(文件大小);
//将istream复制到缓冲区中
std::copy(std::istreambuf_迭代器(位图),std::istreambuf_迭代器(),buffer.begin());
//获取文件的SDL_RWops结构
SDL_RWops*rw=SDL_rwfrommmem(&buffer[0],buffer.size());
//使用SDL_RWops结构进行操作
你的意思是你想从一个istream创建一个RWops结构?那不是一个成功的例子,我不明白你想做什么。我试图从istream读取SDL数据(就像SDL_图像中的图像),我已经写过我不能这样做,因为我不想将整个文件预加载到内存中。如果我想从文件中读取,我会使用IMG_Load:)。我想从通过istream访问的自定义容器加载。您只提到这是一个问题,因为“您事先不知道文件的大小”是的,这可以用于任何istream,我只是使用了一个istream作为示例,因为这是制作istream的最简单方法。叹气。。。想象一下--我从一个文件归档库中得到一个istream。没有尺寸,只是一个istream。此外,在该zipfile中,存储了多个文件。预加载文件将加载1GB的图像。使用rwops->type,您可以允许istream、ostream或iostream。使用NULL作为写入函数似乎很可怕。最好创建一个使用SDL_SetError并返回-1的函数。@Caspin,谢谢,非常有用的提示!尽管如此,发布的代码仍然不起作用。。。。我正在尝试调试它,但没有任何线索:/好的,我的错,我没有将ios::binary传递给测试用例:)