zoukankan      html  css  js  c++  java
  • OpenFileMapping失败 原因ERROR_FILE_NOT_FOUND

    两个win32 console的工程,每个代表一个进程,利用共享内存在两个进程之间通信,过程中遇到了OpenFileMapping失败 原因ERROR_FILE_NOT_FOUND的错误,google了很久没找到原因,下午终于找到原因了。

    两个工程的公共代码部分:

    #include "stdafx.h"
    #include
    <iostream>
    #include
    <windows.h>
    #include
    <cassert>
    using namespace std;

    #define SHARE_MEMORY_NAME TEXT("shareMemoryName")
    #define SHARE_MEMORY_SIZE_NAME TEXT("shareMemorySizeName")

    typedef
    enum
    {
    LX_OK
    = 0, // 正常返回
    LX_SHAREDMEMORY_EXISTS = 1, // 共享内存已经存在
    LX_INVALID_SHAREDMEMORY = 2, // 共享内存错误返回
    LX_INVALID_SIZE = 3 // 共享内存大小错误
    }LX_RETURN_VALUE;

    // 创建共享内存
    LX_RETURN_VALUE CreateSharedMemory(UINT nSize);
    // 释放共享内存
    LX_RETURN_VALUE ReleaseSharedMemory();
    // 得到共享内存大小
    LX_RETURN_VALUE GetSharedMemorySize(UINT& nSize);
    // 向共享内存写入数据
    LX_RETURN_VALUE WriteToSharedMemory(void *pData, UINT nSize);
    // 从共享内存读取数据
    LX_RETURN_VALUE ReadFromSharedMemory(void *pData, UINT nSize);


    class CAutoMutex
    {
    public:
    CAutoMutex()
    {
    Create(TEXT(
    "mutex"));
    Wait();
    }

    ~CAutoMutex()
    {
    Release();
    }

    private:

    bool Create(TCHAR* pName)
    {
    m_mutex
    = ::CreateMutex(NULL, FALSE, pName);
    if (m_mutex == NULL || ::GetLastError() == ERROR_ALREADY_EXISTS)
    {
    return false;
    }
    else
    return true;
    }

    void Release()
    {
    if (m_mutex != NULL)
    {
    ReleaseMutex(m_mutex);
    CloseHandle(m_mutex);
    m_mutex
    = NULL;
    }
    }

    bool Wait()
    {
    UINT32 ret
    = ::WaitForSingleObject(m_mutex, 0);
    if (WAIT_FAILED == ret || WAIT_TIMEOUT == ret)
    {
    return false;
    }
    else
    return true;
    }

    // 互斥量
    HANDLE m_mutex;
    };



    LX_RETURN_VALUE CreateSharedMemory(UINT nSize)
    {
    // 创建共享内存块
    HANDLE hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, nSize, SHARE_MEMORY_NAME);

    // 创建错误
    if ((hFileMapping == NULL) || (hFileMapping == INVALID_HANDLE_VALUE))
    return LX_INVALID_SHAREDMEMORY;

    // 共享内存已经存在
    if (GetLastError() == ERROR_ALREADY_EXISTS)
    return LX_SHAREDMEMORY_EXISTS;

    // 创建另外一块内存存放共享内存的大小
    HANDLE hSize = CreateFileMapping(NULL, NULL, PAGE_READWRITE, 0, sizeof(UINT), SHARE_MEMORY_SIZE_NAME);

    if ((hSize == NULL) || (hSize == INVALID_HANDLE_VALUE) || (GetLastError() == ERROR_ALREADY_EXISTS))
    return LX_INVALID_SHAREDMEMORY;

    // 得到存放共享内存大小的指针
    UINT *pSize = (UINT *)MapViewOfFile(hSize, FILE_MAP_WRITE, 0, 0, sizeof(UINT));

    if (pSize == NULL)
    return LX_INVALID_SHAREDMEMORY;

    // 写入共享内存的大小
    memcpy(pSize, &nSize, sizeof(UINT));


    // FlushViewOfFile(hSize,
    sizeof(UINT));

    UnmapViewOfFile(pSize);

    return LX_OK;
    }

    LX_RETURN_VALUE ReleaseSharedMemory()
    {
    CAutoMutex MutexLock;

    // 打开共享内存
    HANDLE hFileMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, SHARE_MEMORY_NAME);

    // 关闭共享内存
    if (hFileMapping != NULL)
    CloseHandle(hFileMapping);

    // 打开存放共享内存大小的文件映射
    HANDLE hSize = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, SHARE_MEMORY_SIZE_NAME);

    // 关闭存放共享内存大小的文件映射
    if (hSize != NULL)
    CloseHandle(hSize);

    return LX_OK;
    }

    LX_RETURN_VALUE GetSharedMemorySize(UINT
    & nSize)
    {
    CAutoMutex MutexLock;

    HANDLE hSize
    = OpenFileMapping(FILE_MAP_READ, FALSE, SHARE_MEMORY_SIZE_NAME);

    if (hSize == NULL)
    return LX_INVALID_SHAREDMEMORY;

    UINT
    *pSize = (UINT *)MapViewOfFile(hSize, FILE_MAP_READ, 0, 0, sizeof(UINT));

    if (pSize == NULL)
    return LX_INVALID_SHAREDMEMORY;

    // 得到共享内存的大小
    memcpy(&nSize, pSize, sizeof(UINT));

    return LX_OK;
    }

    LX_RETURN_VALUE WriteToSharedMemory(
    void *pDate, UINT nSize)
    {
    UINT nSharedMemorySize
    = 0;

    // 得到共享内存的大小
    if (GetSharedMemorySize(nSharedMemorySize) != LX_OK)
    return LX_INVALID_SHAREDMEMORY;

    // 检查共享内存的大小
    if (nSize > nSharedMemorySize)
    return LX_INVALID_SIZE;

    CAutoMutex MutexLock;

    HANDLE hFileMapping
    = OpenFileMapping(FILE_MAP_WRITE, FALSE, SHARE_MEMORY_NAME);

    if (hFileMapping == NULL)
    return LX_INVALID_SHAREDMEMORY;

    void *pMapView = MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, nSize);

    if (pMapView == NULL)
    return LX_INVALID_SHAREDMEMORY;

    // 清空共享内存
    memset(pMapView, 0, nSharedMemorySize);

    // 将数据写入共享内存
    memcpy(pMapView, pDate, nSize);

    UnmapViewOfFile(pMapView);

    return LX_OK;
    }

    LX_RETURN_VALUE ReadFromSharedMemory(
    void *pData, UINT nSize)
    {
    UINT nSharedMemorySize
    = 0;

    if (GetSharedMemorySize(nSharedMemorySize) != LX_OK)
    return LX_INVALID_SHAREDMEMORY;

    if (nSize > nSharedMemorySize)
    return LX_INVALID_SIZE;

    CAutoMutex MutexLock;

    HANDLE hFileMapping
    = OpenFileMapping(FILE_MAP_READ, FALSE, SHARE_MEMORY_NAME);

    if (hFileMapping == NULL)
    return LX_INVALID_SHAREDMEMORY;

    void *pMapView = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, nSize);

    if (pMapView == NULL)
    return LX_INVALID_SHAREDMEMORY;

    // 从共享内存读取数据
    memcpy(pData, pMapView, nSize);

    UnmapViewOfFile(pMapView);

    return LX_OK;
    }

      

    写共享内存的进程:

    int _tmain()
    {
    LX_RETURN_VALUE rv;
    rv
    = CreateSharedMemory(1024);
    assert(rv
    == LX_OK);

    struct Test
    {
    int x;
    int y;
    };

    Test t;
    t.x
    = 10;
    t.y
    = 100;

    rv
    = WriteToSharedMemory(&t, sizeof(t));
    assert(rv
    == LX_OK);

    wcout
    <<"write to shared memory"<<endl;

    getchar();

    return 0;
    }

      读共享内存的进程:

    int _tmain()
    {
    LX_RETURN_VALUE rv;

    struct Test
    {
    int x;
    int y;
    };

    Test t;

    rv
    = ReadFromSharedMemory(&t, sizeof(t));
    assert(rv
    == LX_OK);

    wcout
    <<"read from shared memory:"<<endl;

    wcout
    <<t.x<<endl<<t.y<<endl;

    rv
    = ReleaseSharedMemory();

    return 0;
    }

    OPenFileMapping失败的原因是:

    第一个进程运行之后马上关闭,所以一定要加上getchar();这句话,并且读进程读共享内存的时候,写进程不能关闭!

  • 相关阅读:
    sosreport -a --report
    笔记本用HDMI转VGA 使用双屏办公 听语音
    1080p就是1920*1080,2k就是2560*1440,4k就是3840*2160
    linux命令截取文件最后n行(所有命令)
    http://www.loongnix.org/index.php/Lbrowser
    tar解压某个目录 tar解压某个指定的文件或者文件夹
    解析CentOS 8上的Xrdp服务器安装
    CentOS、RHEL、Asianux、Neokylin、湖南麒麟、BC Linux、普华、EulerOS请参考“1.1 CentOS本地源配置”;
    Ubuntu18.04制作本地源
    js获取页面高度
  • 原文地址:https://www.cnblogs.com/kex1n/p/2133926.html
Copyright © 2011-2022 走看看