用文件映射(File Mapping)实现进程间内存共享[转]

 我们知道,在Windows中的每个进程都有自己独立的内存空间。该独立的内存空间包含了所有的可执行模块或DLL模块的代码和数据以及动态内存分配的空间。每个进程的内存空间只能被该进程访问,其他进程是不能访问的。
    如果我们要想在进程间共享内存(也就是创建一块不同进程都能访问的内存),那就必须使用内核对象。因为内核对象由Windows系统内核所拥有,而不是由进程所拥有。
    下面就用文件映射(File Mapping)和互斥量(Mutex)两中内核对象来实现简单的进程间内存共享。文件映射(File Mapping)用来开辟共享的内存空间,而互斥量(Mutex)则是用来使读写互斥。
    在该例子里,实现了下面5个函数用来进行进程间的内存共享。可以把这5个函数放到一个DLL里面当成输出函数来用。在进程里加载该DLL并调用相应的函数就可实现进程间内存共享。
    首先,定义返回值代码:
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);
    下面是函数的实现:
//  自动Lock和Unlock互斥量
struct  CAutoMutex
{
    CAutoMutex();
    
~ CAutoMutex();

    
//  互斥量
     static  CMutex m_mutex;
};

CMutex CAutoMutex::m_mutex(FALSE, 
" StarLeeMutex " );

CAutoMutex::CAutoMutex()
{
    m_mutex.Lock();
}

CAutoMutex::
~ CAutoMutex()
{
    m_mutex.Unlock();
}

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

    
//  创建错误
     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),  " StarLeeSharedMemorySize " );

    
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));

    UnmapViewOfFile(pSize);

    
return  LX_OK;
}

LX_RETURN_VALUE ReleaseSharedMemory()
{
    CAutoMutex MutexLock;

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

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

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

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

    
return  LX_OK;
}

LX_RETURN_VALUE GetSharedMemorySize(UINT
&  nSize)
{
    CAutoMutex MutexLock;

    HANDLE hSize 
=  OpenFileMapping(FILE_MAP_READ, FALSE,  " StarLeeSharedMemorySize " );

    
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,  " StarLeeSharedMemory " );

    
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,  " StarLeeSharedMemory " );

    
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值