2011-11-19 98 views
11

下面是一个使用WinAPI的的WriteFile的一个 “Hello World” 程序(编译在Microsoft Visual C++ 2008年速成):为什么WriteFile在写入标准输出时崩溃?

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    wchar_t str[] = L"Hello world"; 

    HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); 
    if(out && out!=INVALID_HANDLE_VALUE) 
    { 
     WriteFile(out, str, sizeof(str), NULL, NULL); 
     CloseHandle(out); 
    } 

    return 0; 
} 

如果在一个控制台窗口中执行,它高兴地迎接世界。但是,如果您尝试重定向其标准输出,则如

hello.exe > output.txt 

程序在WriteFile(NULL指针异常)中崩溃。尽管如此,output.txt存在并且包含完整的正确输出。

上崩溃的调用堆栈:

[email protected]() + 0x75 bytes  
[email protected]() + 0x4e bytes  
srgprc2.exe!wmain(int argc=1, wchar_t * * argv=0x00483d88) Line 15 + 0x16 bytes C++ 

消息: “访问冲突写入位置00000000未处理的异常在0x75ce85ea(KernelBase.dll)在srgprc2.exe:0000005。”

这是怎么回事吗?谢谢!

+3

删除CloseHandle()调用。 –

+0

...应该清楚,因为您正在使用“Get ...”功能,而不是“Open ...”功能。 –

+0

CloseHandle甚至没有调用,崩溃发生在WriteFile中,程序终止。 – user38329

回答

17

第四个参数为WriteFileis not optional。您传递NULL,这是不允许的。

+3

D'OH! “只有当lpOverlapped参数不为NULL时,此参数才可以为NULL。” http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747%28v=vs.85%29.aspx – Mordachai

+0

谢谢。原型中的“__out_opt”使我困惑不解。 – user38329

+0

我也遇到与问题中提到的OP相同的问题。据我记得,我也通过NULL的参数。所以......感谢您的杰出答案。并且是... +1 :) –

0

第四个参数(它告诉我们多少字节是如何实际写入)期待指针DWORD值(又名无符号整数),当你传递NULL给它试图写入DWORD到空指针导致的异常,而不是参数只有传递指向该参数的指针才是必需的,但是在写入之后也应该始终检查它的值,因为尽管有些可能,但WriteFile将写入的数据少于您提供的数据。

相关问题