0

我有一个大程序在使用 sdl_rwops 时导致访问冲突。所以我决定创建一个小程序来测试 sdl_rwops,它导致了同样的访问冲突。对于我所看到的,这是由于 fopen_s() 部分引起的,但我不知道为什么。也许你们能找到我所缺少的。这是代码:

#include "SDL.h"
#include < stdio.h >

int main(int argc, char *argv[]) 
{
  FILE *file;
  SDL_Surface *screen;
  SDL_Surface *one;
  SDL_Rect rect;
  errno_t err;

/* This is the RWops structure we'll be using */

  SDL_RWops *rw;
  SDL_Init(SDL_INIT_VIDEO);
  atexit(SDL_Quit);
  screen = SDL_SetVideoMode(640, 480, 16, SDL_DOUBLEBUF);

/* Here we get a file pointer to a bitmap */

  if ( (err = fopen_s(&file,"penguin.bmp", "r")) != 0)
  {
     printf("Couldn't load penguin.bmp\n");
     exit(1);
  }

/* This is where we actually create our RWops structure.  Here we're
 instructing SDL to get it from the file pointer we just opened */

rw = SDL_RWFromFP(file, 0);

/* SDL_LoadBMP_RW is the RWops version of the old standby,
 SDL_LoadBMP.  This will get the image from the RWops you passed
 in; in this case the file you've opened */

one = SDL_LoadBMP_RW(rw, 0); // This line calls fopen.c and causes the crash

/* Clean up after ourselves */
SDL_FreeRW(rw);
fclose(file);

/* Haphazard way of getting stuff to the screen */
rect.x = rect.y = 20;
rect.w = one -> w;
rect.y = one -> h;
SDL_BlitSurface(one, NULL, screen, &rect);

SDL_Flip(screen);

SDL_Delay(3000);
}

这是导致程序崩溃的 fopen.c 部分:

errno_t __cdecl _tfopen_s (
FILE ** pfile,
const _TSCHAR *file,
const _TSCHAR *mode)
{

_VALIDATE_RETURN_ERRCODE((pfile != NULL), EINVAL);

*pfile = _tfsopen(file, mode, _SH_SECURE); // This line causes the access violation

if(*pfile != NULL)
   return 0;

return errno;
}

线

one = SDL_LoadBMP_RW(rw, 0);

跳转到 fopen.c 和该行

*pfile = _tfsopen(file, mode, _SH_SECURE);

在该文件中使其崩溃。

我使用的是 Visual Studio 2012,图片与可执行文件位于同一文件夹中。SDL.dll 甚至 SDL_image.dll 也在那里。我在谷歌上发现了一个关于同样问题的帖子,那个人说当他把整个路径(而不是只是 penguin.bmp“)它不会崩溃。它对我不起作用,反正崩溃了。我开始思考这可能是一些 SDL 初始化问题,但我做了任何我可以在谷歌上找到的东西,但没有任何效果。我尝试在多线程 DLL (/Md) 中运行,在多线程调试 Dll (/MDd) 中,尝试以 64 位运行,厌倦了将子系统更改为 Windows 和控制台……一切都导致了同样的崩溃。

4

1 回答 1

3

如果您阅读了 SDL_RWFromFP 的文档

描述

SDL_RWFromFP 从文件指针创建一个新的 SDL_RWops 结构,用 stdio 打开。如果 autoclose 不为零,则当 RWops 结构关闭时,文件将自动关闭。

注意:这在 Win32 下不可用,因为在该平台上的应用程序中打开的文件不能被动态链接库使用。

注意:此功能在 SDL-1.2-svn4446 中不存在

因此,如果要使用 RWOps,则需要使用 SDL_RWFromFile。

SDL 2 也比 SDL 1.* 有很多改进,我强烈建议切换到它。

于 2013-08-23T18:57:28.163 回答