Windows 7共享内存的奇怪错误

时间:2015-07-06 02:45:05

标签: c++ windows

尝试学习一些关于Windows 7共享内存的基础知识。我根据一个例子创建了以下内容,它编译得很好,当我运行它时

c:\temp> a.exe  tmp.txt 85

它没有像我预期的那样从文件中产生10个字节,相反,它只打印了10个空字节。知道为什么吗?

由于

==============这是测试程序=============

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>


int _tmain(int argc, char *argv[])
{
   HANDLE hMapFile;
   LPCTSTR pBuf;
    //printf("argv[1] %s\n", argv[1]); exit(0);
   hMapFile = CreateFileMapping(
                 INVALID_HANDLE_VALUE,    // use paging file
                 NULL,                    // default security
                 PAGE_READONLY,          // read/write access
                 0,                       // maximum object size (high-order DWORD)
                 atoi(argv[2]),            // maximum object size (low-order DWORD)
                 argv[1]);                 // name of mapping object

   if (hMapFile == NULL)
   {
      _tprintf(TEXT("Could not create file mapping object (%d).\n"),
             GetLastError());
      return 1;
   }
   pBuf = (LPTSTR) MapViewOfFile(hMapFile,   // handle to map object
                        FILE_MAP_READ,     // read/write permission
                        0,
                        0,
                        atoi(argv[2]));  //BUF_SIZE);

   if (pBuf == NULL)
   {
      _tprintf(TEXT("Could not map view of file (%d).\n"),
             GetLastError());

       CloseHandle(hMapFile);

      return 1;
   }
    int i;
    for (i=0; i<10; i++) {
        printf("%02x ", pBuf[i]);
    }
    printf("\n");
    return 0;
}*

1 个答案:

答案 0 :(得分:2)

您正在打印空内存,这就是您看到空值的原因。你必须在内存中放置一些东西而不是零。正如您在MapViewOfFile文档中看到的那样,页面文件的映射视图始终初始化为仅包含零。

您已在内存中正确分配了只读部分,并以页面文件为后盾。你无法写信给它,因为它是只读的。但是,如果要使其可写,则可以将一些字节写入内存,然后再将其读回。

相反,您可以使用现有文件来支持映射,并假设文件不是空的,您将能够从该文件中读取字节。看起来,基于你调用程序的参数,你试图映射tmp.txt。如果是这种情况,则需要使用CreateFile打开该文件,然后将生成的HANDLE作为第一个参数传递给CreateFileMapping。一旦你这样做,输出应该与文件的内容匹配。

下面的代码假设一个64位系统和一个全ASCII文件名。它也不会从CreateFileA,CreateFileMappingA或MapViewOfFile中清理资源。

void map_file(const char * fname) {
    HANDLE file = CreateFileA(fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (file == INVALID_HANDLE_VALUE) {
        throw runtime_error("Unable to open file");
    }

    LARGE_INTEGER file_size = {0};
    if (!GetFileSizeEx(file, &file_size)) {
        throw runtime_error("Unable to get file size");
    }

    if (file_size.QuadPart == 0) {
        throw runtime_error("File cannot be empty");
    }

    HANDLE mapping = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL);
    if (mapping == nullptr) {
        throw runtime_error("Unable to map file");
    }

    uint8_t * view = (uint8_t *) MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, (size_t) file_size.QuadPart);
    if (view == nullptr) {
        throw runtime_error("Unable to map view of file");
    }

    // do something with 'view'
}