C 在调试模式下编译时,GetOpenFileName永远不会返回(VS2010)

C 在调试模式下编译时,GetOpenFileName永远不会返回(VS2010),c,visual-studio-2010,winapi,getopenfilename,visual-leak-detector,C,Visual Studio 2010,Winapi,Getopenfilename,Visual Leak Detector,当我在调试模式下编译程序时,GetOpenFileName(&ofn)永远不会返回 它在释放模式下工作得非常好。我能发现的唯一区别是很多东西在发布模式下都在优化 OPENFILENAME; TCHAR szFile[MAX_PATH]; szFile[0]='\0'; szFile[1]='\0'; //初始化OPENFILENAME 零内存(&ofn,sizeof(ofn)); ofn.L结构尺寸=尺寸ofn; ofn.hwndOwner=NULL; ofn.lpstrFile=szFile;

当我在调试模式下编译程序时,
GetOpenFileName(&ofn)
永远不会返回

它在释放模式下工作得非常好。我能发现的唯一区别是很多东西在发布模式下都在优化

OPENFILENAME;
TCHAR szFile[MAX_PATH];
szFile[0]='\0';
szFile[1]='\0';
//初始化OPENFILENAME
零内存(&ofn,sizeof(ofn));
ofn.L结构尺寸=尺寸ofn;
ofn.hwndOwner=NULL;
ofn.lpstrFile=szFile;
ofn.lpstrFile[0]='\0';
ofn.nMaxFile=最大路径;
ofn.lpstrFilter=TEXT(“图像(*.jpg;*.png;*.bmp;*.tga;*.psd)\0*.jpg;*.png;*.bmp;*.tga;*.psd\0\0”);
ofn.lpstrInitialDir=文本(“.”);
ofn.lpstrTitle=文本(“打开512x512图像”);
ofn.Flags=ofn_路径必须存在| ofn_文件必须存在;
...
GetOpenFileName(&ofn)
我正在使用Unicode字符集进行编译

如果我从n.lpstrFilter的
中间删除
\0
,它将在调试模式下工作,但显然过滤器无法正常工作

以下是在
\0
点附近的调试和释放模式下,内存中字符串的外观:

...snip...
0x00364BB4  70 00  p.
0x00364BB6  73 00  s.
0x00364BB8  64 00  d.
0x00364BBA  29 00  ).
0x00364BBC  00 00  ..
0x00364BBE  2e 00  ..
0x00364BC0  6a 00  j.
0x00364BC2  70 00  p.
0x00364BC4  67 00  g.
0x00364BC6  3b 00  ;.
...snip...
我可能在做一些愚蠢的事情(我没有太多winapi/w Unicode的经验),但我不知道是什么。有什么想法吗

编辑:使用当前代码更新。

基本上

ofn.lpstrFilter = TEXT("Images (*.jpg;*.png;*.bmp;*.tga;*.psd)*.jpg;*.png;*.bmp;*.tga;*.psd\0");
                                                              ^
有效,但是

ofn.lpstrFilter = TEXT("Images (*.jpg;*.png;*.bmp;*.tga;*.psd)\0*.jpg;*.png;*.bmp;*.tga;*.psd\0");
                                                              ^
没有

EDIT:尝试在fresh Visual Studio项目中复制相同的错误,但无法执行。它起作用了。对项目设置进行了区分,没有任何区别。

一些事情

1) 您正在初始化
lpstrFile
两次

ofn.lpstrFile = szFile;
ofn.lpstrFile = TEXT('\0');
2) 您应该初始化
szFile
(可能是您在#1中的意图):

3)
nMaxFile
应为最大字符数,而不是字节数。因此,您需要
MAX_PATH
sizeof(szFile)/sizeof(TCHAR)。


4) 文件筛选器中缺少一个“*”:应该是N的*.jpg

1
。lpstrFilter
应以两个零终止:
\0\0

2您确定
ZeroMemory()
真的将N
的内容的
归零了吗。您可以试试
SecureZeroMemory()

参考2 a:

使用此[SeCurZeMeMyRy]()函数而不是ZeMeMoRy,当您希望确保数据将被立即覆盖时,因为某些C++编译器可以通过完全删除它来优化对零内存的调用。


我只需使用
memset()

我最终分离出构建之间的唯一区别:

我在调试构建中使用了。移除后,它开始工作

我将试图弄清为什么会发生这种情况,但我只想感谢每一个试图帮助我的人。我希望我能奖励更多的分数

还有一些人有类似的问题:


编译器应自动追加第二个。即使在末尾手动添加2个空字符也不能解决问题。是的,我打算使用
memset()
重写它,部分是从使用
ZeroMemory()
的文档中复制粘贴代码,但它不能解决问题。这可能是在我试图让它工作时介绍的:是的,从一开始就没有注意到#3,但仍然没有。如果我从过滤器中间删除空字符,即使使用稍微不正确的代码也可以在发布和调试中工作。所以这有点棘手。当你说“GetOpenFileName永不返回”时,你的意思是对话框出现并正常工作,但当你单击“确定”或“取消”时会锁定。或者,对话框根本不出现吗?@cbranch,它根本不出现。它似乎在无限循环中,但由于我没有调试数据,所以只剩下反汇编数据。因为有点痛,我没试着弄清楚里面发生了什么。我很确定,由于某种原因,它无法解析过滤器,只是进入了一个试图解析它的循环。但是我不知道为什么。我们可以假设您没有对ofn进行其他初始化,但是您在发布的代码中显示了这样的初始化吗?如果您的过滤器有问题,它不会向我跳出来。在末尾有一个额外的(冗余的)空终止符,但这并不重要。这是编译成.exe还是.dll?您使用的是什么版本的Windows?如果将lpstrInitialDir设置为NULL会发生什么情况?我想我从来没有使用过这样的相对路径。我使用空路径或完整路径。请注意:它似乎已被修复,并与2.5()版一起发布
TCHAR szFile[MAX_PATH];
szFile[0] = '\0';