为什么在 stdio 函数上使用 SDL I/O 函数?

Why use the SDL I/O functions over the stdio functions?

SDL 包含许多以 SDL_RWops 结构为中心处理 I/O 的函数。它们中的很多与 stdio I/O 函数非常相似,以至于它们使用相同样式的字符串。例如,fopen 与 SDLRWFromfile。

为什么会这样?我应该在标准库上使用 SDL I/O 函数吗? SDL 函数是否更便携?

SDL_RWops 的有趣之处在于它只是一个带有函数指针的接口结构,用于 read/write/seek/close...

typedef struct SDL_RWops {
    /** Seek to 'offset' relative to whence, one of stdio's whence values:
     *  SEEK_SET, SEEK_CUR, SEEK_END
     *  Returns the final offset in the data source.
     */
    int (SDLCALL *seek)(struct SDL_RWops *context, int offset, int whence);

    /** Read up to 'maxnum' objects each of size 'size' from the data
     *  source to the area pointed at by 'ptr'.
     *  Returns the number of objects read, or -1 if the read failed.
     */
    int (SDLCALL *read)(struct SDL_RWops *context, void *ptr, int size, int maxnum);

    /** Write exactly 'num' objects each of size 'objsize' from the area
     *  pointed at by 'ptr' to data source.
     *  Returns 'num', or -1 if the write failed.
     */
    int (SDLCALL *write)(struct SDL_RWops *context, const void *ptr, int size, int num);

    /** Close and free an allocated SDL_FSops structure */
    int (SDLCALL *close)(struct SDL_RWops *context);
  // ... there are other internal fields too
 }

当使用实例 SDL_LoadBMP 时,SDL 从文件句柄创建一个 SDL_RWops 对象,但您也可以从其他来源创建 SDL_RWops 对象,例如内存位置,例如对于不提供本地文件系统的系统(任天堂 DS 浮现在脑海中,即使像 R4 或 M3 这样的自制链接器车通常能够提供这样的服务)。

来自 SDL_Video.h:

/**
 * Load a surface from a seekable SDL data source (memory or file.)
   ...
 */
extern DECLSPEC SDL_Surface * SDLCALL SDL_LoadBMP_RW(SDL_RWops *src, int freesrc);

/** Convenience macro -- load a surface from a file */
#define SDL_LoadBMP(file)   SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1)

所以SDL_LoadBMP是一个调用SDL_RWFromFile(file, "rb")的宏,它当然使用标准库来创建文件句柄并创建一个SDL_RWop对象,函数指针初始化为标准库现有 readwriteseekclose 函数。

在这种情况下,您可以将资产作为字节数组硬编码在可执行二进制文件中,并在该内存上映射一个 SDL_RWops 对象。

所以对于 SDL 函数,您必须使用它们(即使它们的使用是隐藏的)。但是如果您有其他资源文件(如音频、配置文件)没有提供给 SDL,您可以使用标准库来读取它们。