我有一个大程序,在使用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也在那里。 我在google上发现了一个同样问题的帖子,而且当他把整个路径(而不仅仅是penguin.bmp“)放在一起时,它就不会崩溃。它对我不起作用,无论如何都会崩溃。 我开始认为它可能是一些SDL初始化问题,但我做了一些我在谷歌上找到的东西,没有任何效果。我尝试在多线程DLL(/ Md)中运行,在多线程调试DLL(/ MDd)中运行,尝试以64位运行,将子系统更改为Windows并控制台...一切都导致同样的崩溃。< / p>
答案 0 :(得分:3)
如果您阅读了SDL_RWFromFP
的文档描述
SDL_RWFromFP从文件指针创建一个新的SDL_RWops结构,用stdio打开。如果autoclose非零,则在关闭RWops结构时文件将自动关闭。
注意:这在Win32下不可用,因为动态链接库无法使用该平台上的应用程序中打开的文件。
注意:SDL-1.2-svn4446
中不存在此功能
如果你想使用RWOps,你需要使用SDL_RWFromFile。
SDL 2与SDL 1相比有许多改进。*我强烈建议改用它。