在LockFileEx之后调用ReadFile时崩溃

我有几个尝试读取和写入相同文件的进程。 我希望他们每个人都锁定文件,以便其中只有一个一次访问它。

我试过这个( 编辑:这次是一个完整的测试代码 ):

#include "stdafx.h" #include "Windows.h" bool test() { const char* path = "test.txt"; HANDLE hFile = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { printf("ERROR: Cannot open file %s\n", path); return false; } // Lock the file { OVERLAPPED overlapped = {0}; BOOL res = LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, ~0, ~0, &overlapped); if (!res) { printf("ERROR: Cannot lock file %s\n", path); return false; } } DWORD fileSize = GetFileSize(hFile, NULL); if (fileSize > 0) { char* content = new char[fileSize+1]; // Read the file BOOL res = ReadFile(hFile, content, fileSize, NULL, NULL); if (!res) { printf("ERROR: Cannot read file %s\n", path); } delete[] content; } const char* newContent = "bla"; int newContentSize = 3; // Write the file BOOL res = WriteFile(hFile, newContent, newContentSize, NULL, NULL); if (!res) { //int err = GetLastError(); printf("ERROR: Cannot write to file\n"); } // Unlock the file { OVERLAPPED overlapped = {0}; UnlockFileEx(hFile, 0, ~0, ~0, &overlapped); } CloseHandle(hFile); return true; } int _tmain(int argc, _TCHAR* argv[]) { bool res = test(); return 0; } 

这在我的计算机上工作正常,它有Windows 8.但在我的同事的计算机上,它有Windows 7,它崩溃了。 具体来说,对ReadFile和WriteFile的调用始终会崩溃。

请注意,它永远不会输入错误printfs的代码路径。 除了在ReadFile 中的位置0x00000000处写入时 (在Windows 7上运行时),此代码不会触发任何错误。

我们还试图将重叠的结构传递给ReadFile和WriteFile调用。 它可以防止崩溃,但锁不再起作用,文件全部被扰乱(不是这个测试代码,真实代码)。

我究竟做错了什么?

看起来你的问题是:

lpNumberOfBytesRead [out,optional]参数在您的调用中为null。

仅当lpOverlapped参数为NULL时,此参数才可以为NULL。

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx

inheritance人你的问题:

您缺少必要的struct-member 并且

0~0以及{0}都是坏代码 ,像这样的常量表达式总会产生预期的结果 – WINAPI不像libc那样工作, 参数并不总是与常量进行比较 ,而是针对/通过宏和其他预处理器进行测试 -定义本身所以传递常量值或用常量初始化WINAPI结构通常会导致这样的错误

经过多年的实验,我发现只有一种方法可以避免它们,我会用更正的代码表达它:

 OVERLAPPED overlapped; overlapped.hEvent = CreateEvent( ........... ); // put valid parameters here! UnlockFileEx(hFile, 0 /*"reserved"*/, ULONG_MAX, ULONG_MAX, &overlapped); 

请仔细阅读: http : //msdn.microsoft.com/en-us/library/windows/desktop/aa365716%28v=vs.85%29.aspx