在VS 2008中调用_osfile()时出现断言错误?

6
我有一个C++代码库已经运行了很长时间。这个代码库是一个传统的VS 2003项目集,我最近将其迁移到了VS 2008。迁移似乎是成功的,因为生成的程序可以构建和运行。
我在新的驱动器上重新安装了操作系统和所有应用程序,现在当我尝试在调试器中调试程序时,我会收到CRT的chsize(实际上是_chsize_s)内的断言错误。具体来说(裁剪了必要部分,忽略了安全检查):
FILE * testfile = fopen("P:\\_Dan\\local\\foogoo.txt", "w");
int filehandle = fileno(testfile);
chsize(filehandle, 0);
fwrite("goohoo", 1, 6, testfile);
fclose(testfile);

调试断言出现在chsize中,具体来说,在CRT的源代码文件chsize.c中,在以下行内:

 _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE((_osfile(filedes) & FOPEN), EBADF);

...其中filedesfilehandle匹配。

我认为问题可能是由于新系统上没有安装旧版本的VS(只有VS 2008),因为一些第三方库需要VS 8.0可再发行版 - 即使在旧系统上使用VS 2008似乎构建和运行一切正常。因此,我安装了VS 2005(而不是2003)。但是,问题仍然存在。

任何建议都将不胜感激。

*更新-该问题与chsize无关。请参见下面的答案。


既然你裁剪了它,你能确认一下你测试过testfile!= NULL吗?此外,请注意MSDN文档说chsize自VS2005起已被弃用:http://msdn.microsoft.com/en-us/library/ms235502(v=VS.90).aspx-他们提供了替代方案。 - holtavolt
谢谢您的询问 - 是的,我仔细确认了testfile!= null。无论如何 - 我解决了这个问题 - 这是涉及到c-runtime线程模型选择不匹配(请参见我的答案),与chsize无关。 - Dan Nissenbaum
2个回答

7
问题已解决 - 与 chsize 无关。在代码生成中选择的 C 运行库链接模型为主项目设置为多线程调试(/MTd),但是对于它链接到的解决方案中的所有项目,都设置为多线程调试 DLL(/MDd)。改为 /MDd 可以解决该问题。
我熟悉这些链接问题,并通常会小心地设置它们,但由于这是从早期版本的 Visual Studio 升级而来的工作项目,没有任何更改,所以我没有想到要深入探究。我没有调查设置是如何或为什么发生改变(甚至是否在之前的版本中设置为此方式但并没有引起问题)。

丹,你是一个了不起的存在,拥有一颗充满爱的心,我想向你表达我的钦佩,感谢你12年前所付出的关怀。XoXo. - Mathieu Westphal
1
不开玩笑,我在类似的问题上苦苦思索了一个多月,而你向我指出了正确的方向。 - Mathieu Westphal

3
发现我的代码也存在这个问题。 主程序需要与使用MT构建的共享库链接。 当在主程序中打开文件处理器并将其传递给共享库的函数时,CRT中setmode.c中的_VALIDATE_RETURN((_osfile(fh) & FOPEN), EBADF, -1)导致程序崩溃。
在汇编模式下调试_osfile,osfile在表__pioinfo (01802EEDB0h)中查找文件处理器。这是静态链接的CRT中的固定区域。而主程序中的另一个__pioinfo是另一个地址01E619540h。 简而言之,如果两个模块需要共享全局数据,则不能使用MT模型构建。
我只想用静态编译优化共享库,可能会出现一些难以注意到的错误。 似乎在大多数情况下,GCC的强制共享或静态编译都是有意义的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接