我有一个大程序在使用 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 和控制台……一切都导致了同样的崩溃。