简单小巧的跨平台共享内存代码
如何使用的示例代码
SHARE_MEM_KEY( SHM_KEY_EXAMPLE , 0x12345678 , "SHM_EXAMPLE" )
ShareMemory ShareMem;
const size_t SHM_LEN_EXAMPLE = 64 * 1024 * 1024;
ShareMem.Create( SHM_KEY_EXAMPLE , SHM_LEN_EXAMPLE );
char * pMemory = ( char * ) ShareMem.Address( );
memset( pMemory , 0 , SHM_LEN_EXAMPLE );
SHARE_MEM_KEY( SHM_KEY_EXAMPLE , 0x12345678 , "SHM_EXAMPLE" )
ShareMemory ShareMem;
const size_t SHM_LEN_EXAMPLE = 64 * 1024 * 1024;
ShareMem.Create( SHM_KEY_EXAMPLE , SHM_LEN_EXAMPLE );
char * pMemory = ( char * ) ShareMem.Address( );
memset( pMemory , 0 , SHM_LEN_EXAMPLE );
ShareMemory.h
//==================================================================================================
// Share Memory
// --------------------------------------------------------------------------------------------
// int Create( KeyT Key , size_t Length );
// int Open( KeyT Key , bool Write = false );
// int Delete( );
// int Close( );
//
// --------------------------------------------------------------------------------------------
// Universal Studio WonKerr 2006-03-25
//==================================================================================================
#pragma once
#if defined( _WIN32 )
# include <windows.h>
#else
# include <sys/types.h>
# include <sys/ipc.h>
# include <sys/shm.h>
#endif
#if defined( _WIN32 )
//==================================================================================================
// Windows : Share Memory Template
template< typename KeyT > class CShareMem_WinX
{
public:
CShareMem_WinX( )
{
hMapping = NULL;
pAddress = NULL;
dwAccess = 0;
}
~CShareMem_WinX( )
{
Delete( );
}
inline int Create( KeyT Key , size_t Length )
{
// 检查参数
if( NULL != pAddress || NULL != hMapping ) return -1;
// 调整长度为页的整数倍 ( 4096 * N )
CONST ULONGLONG AlignToPage = 0x00000000000003FF;
ULONGLONG Length64 = static_cast< ULONGLONG >( Length );
Length64 = ( ( Length64 + AlignToPage ) & ( ~ AlignToPage ) );
// 创建共享内存,在 64 位中大小可以超过 4 GB
HANDLE hFile = static_cast< HANDLE >( INVALID_HANDLE_VALUE );
DWORD dwSizeLow = static_cast< DWORD >( Length64 & 0xFFFFFFFF );
DWORD dwSizeHigh = static_cast< DWORD >( ( Length64 >> 32 ) & 0xFFFFFFFF );
hMapping = CreateFileMapping( hFile , NULL , PAGE_READWRITE , dwSizeHigh , dwSizeLow , Key );
if( hMapping != NULL && GetLastError() == ERROR_ALREADY_EXISTS )
{
// 已经存在
CloseHandle( hMapping );
hMapping = NULL;
return -2;
}
else if( NULL == hMapping )
{
// 创建失败
return -3;
}
// 映射内存
pAddress = MapViewOfFileEx( hMapping , FILE_MAP_ALL_ACCESS , 0 , 0 , Length , 0 );
if( NULL != pAddress ){ dwAccess = INT_MAX ; return ERROR_SUCCESS; }
CloseHandle( hMapping );
hMapping = NULL;
return -4;
}
inline int Open( KeyT Key , bool Write = false )
{
// 检查参数
if( NULL != pAddress || NULL != hMapping ) return -1;
// 打开共享内存
dwAccess = Write ? FILE_MAP_ALL_ACCESS : FILE_MAP_READ ;
hMapping = OpenFileMapping( dwAccess , FALSE , Key );
if( NULL == hMapping ){ dwAccess = 0 ; return -2; }
// 映射内存
pAddress = MapViewOfFileEx( hMapping , dwAccess , 0 , 0 , 0 , 0 );
if( NULL != pAddress ){ dwAccess = INT_MAX ; return ERROR_SUCCESS; }
CloseHandle( hMapping );
hMapping = NULL;
return -3;
}
inline int Delete( )
{
// 检查参数
if( NULL == pAddress || NULL == hMapping ) return -1;
// 删除共享
UnmapViewOfFile( pAddress );
CloseHandle( hMapping );
pAddress = NULL;
hMapping = 0;
dwAccess = 0;
return 0;
}
inline int Close( )
{
return Delete( );
}
inline void * Address()
{
return pAddress;
}
public:
static int Exists( KeyT Key )
{
CShareMem_WinX< KeyT > ShareMem;
return ShareMem.Open( Key );
}
static int Remove( KeyT Key )
{
return 0;
}
protected:
HANDLE hMapping;
LPVOID pAddress;
DWORD dwAccess;
};
//==================================================================================================
// Define share mem key type & template name
#define SHARE_MEM_KEY_TYPE LPCTSTR
#define SHARE_MEM_TEMPLATE CShareMem_WinX
#define SHARE_MEM_KEY( name , key_1 , key_2 ) SHARE_MEM_KEY_TYPE name = TEXT( key_2 );
#else
//==================================================================================================
// System V : Share Memory Template
template< typename T > class CShareMem_SysV
{
public;
CShareMem_SysV( )
{
pAddress = NULL;
hMapping = -1;
nAccess = 0;
}
~CShareMem_SysV( )
{
Delete( );
}
public:
inline int Create( KeyT lpszName , size_t nLength )
{
// Check parameter
if( NULL != pAddress || -1 != hMapping ) return -1;
// Get share memory id
//int iFlags = SHM_R|SHM_W|IPC_CREAT|IPC_EXCL;
hMapping = shmget( Key , Length , IPC_CREAT );
if( -1 == hMapping ){ return -2; }
// Set access mode
//struct shmid_ds shmds;
//shmctl(hMapping , IPC_STAT , &shmds );
//shmds.shm_perm.mode |= 0x1B4; /* rw-rw-r-- */
//shmctl(hMapping , IPC_SET , &shmds );
// Attach share memory
pAddress = shmat( hMapping , 0 , 0 );
if( NULL != pAddress )
{
nAccess = -1;
return 0;
}
// Remove share memory id
int hShare = hMapping; hMapping = -1;
return shmctl( hShare , IPC_RMID , 0 );
}
inline int Delete( )
{
// Check parameter
if( NULL == pAddress || -1 == hMapping ) return -1;
if( -1 != nAccess ) { return Close( ); }
// Detech and remove share memory
shmdt( pAddress ) ; pAddress = NULL;
shmctl( hMapping , IPC_RMID , 0 );
hMapping = -1; nAccess = 0;
return 0;
}
inline int Open( KeyT Key , bool Write = false )
{
// Check parameter
if( NULL != pAddress || -1 != hMapping ) return -1;
// Open share memory
nAccess = Write ? SHM_R : SHM_R | SHM_W ;
hMapping = shmget( Key , 0 , nAccess );
if( -1 == hMapping ) { return -2; }
// Attach share memory
pAddress = shmat( hMapping , 0 , 0 );
return pAddress ? 0 : -3 ;
}
inline int Close( )
{
// Check Parameter
if( NULL == pAddress || -1 == hMapping ) return -1;
if( -1 == nAccess ) { return Delete( ); }
// Share memory detech
void * pAddr = pAddress; pAddress = NULL;
hMapping = -1; nAccess = 0;
return shmdt( pAddr );
}
inline void * Address()
{
return (void *)pAddress;
}
public:
static int Exists( KeyT Key )
{
return shmget( Key , 0 , SHM_R );
}
static int Remove( KeyT Key )
{
int hShare = shmget( Key , 0 , SHM_R | SHM_W );
if( -1 == hShare ){ return 0; }
return shmctl( hShare , IPC_RMID , 0 );
}
protected:
int nAccess;
int hMapping;
char * pAddress;
};
//==================================================================================================
// Define share mem key type & template name
#define SHARE_MEM_KEY_TYPE key_t
#define SHARE_MEM_TEMPLATE CShareMem_SysV
#define SHARE_MEM_KEY( name , key_1 , key_2 ) enum { name = key_1 };
#endif
//==================================================================================================
// Instance Template Class : ShareMemory
typedef SHARE_MEM_TEMPLATE< SHARE_MEM_KEY_TYPE > ShareMemory;
//==================================================================================================
// Share Memory
// --------------------------------------------------------------------------------------------
// int Create( KeyT Key , size_t Length );
// int Open( KeyT Key , bool Write = false );
// int Delete( );
// int Close( );
//
// --------------------------------------------------------------------------------------------
// Universal Studio WonKerr 2006-03-25
//==================================================================================================
#pragma once
#if defined( _WIN32 )
# include <windows.h>
#else
# include <sys/types.h>
# include <sys/ipc.h>
# include <sys/shm.h>
#endif
#if defined( _WIN32 )
//==================================================================================================
// Windows : Share Memory Template
template< typename KeyT > class CShareMem_WinX
{
public:
CShareMem_WinX( )
{
hMapping = NULL;
pAddress = NULL;
dwAccess = 0;
}
~CShareMem_WinX( )
{
Delete( );
}
inline int Create( KeyT Key , size_t Length )
{
// 检查参数
if( NULL != pAddress || NULL != hMapping ) return -1;
// 调整长度为页的整数倍 ( 4096 * N )
CONST ULONGLONG AlignToPage = 0x00000000000003FF;
ULONGLONG Length64 = static_cast< ULONGLONG >( Length );
Length64 = ( ( Length64 + AlignToPage ) & ( ~ AlignToPage ) );
// 创建共享内存,在 64 位中大小可以超过 4 GB
HANDLE hFile = static_cast< HANDLE >( INVALID_HANDLE_VALUE );
DWORD dwSizeLow = static_cast< DWORD >( Length64 & 0xFFFFFFFF );
DWORD dwSizeHigh = static_cast< DWORD >( ( Length64 >> 32 ) & 0xFFFFFFFF );
hMapping = CreateFileMapping( hFile , NULL , PAGE_READWRITE , dwSizeHigh , dwSizeLow , Key );
if( hMapping != NULL && GetLastError() == ERROR_ALREADY_EXISTS )
{
// 已经存在
CloseHandle( hMapping );
hMapping = NULL;
return -2;
}
else if( NULL == hMapping )
{
// 创建失败
return -3;
}
// 映射内存
pAddress = MapViewOfFileEx( hMapping , FILE_MAP_ALL_ACCESS , 0 , 0 , Length , 0 );
if( NULL != pAddress ){ dwAccess = INT_MAX ; return ERROR_SUCCESS; }
CloseHandle( hMapping );
hMapping = NULL;
return -4;
}
inline int Open( KeyT Key , bool Write = false )
{
// 检查参数
if( NULL != pAddress || NULL != hMapping ) return -1;
// 打开共享内存
dwAccess = Write ? FILE_MAP_ALL_ACCESS : FILE_MAP_READ ;
hMapping = OpenFileMapping( dwAccess , FALSE , Key );
if( NULL == hMapping ){ dwAccess = 0 ; return -2; }
// 映射内存
pAddress = MapViewOfFileEx( hMapping , dwAccess , 0 , 0 , 0 , 0 );
if( NULL != pAddress ){ dwAccess = INT_MAX ; return ERROR_SUCCESS; }
CloseHandle( hMapping );
hMapping = NULL;
return -3;
}
inline int Delete( )
{
// 检查参数
if( NULL == pAddress || NULL == hMapping ) return -1;
// 删除共享
UnmapViewOfFile( pAddress );
CloseHandle( hMapping );
pAddress = NULL;
hMapping = 0;
dwAccess = 0;
return 0;
}
inline int Close( )
{
return Delete( );
}
inline void * Address()
{
return pAddress;
}
public:
static int Exists( KeyT Key )
{
CShareMem_WinX< KeyT > ShareMem;
return ShareMem.Open( Key );
}
static int Remove( KeyT Key )
{
return 0;
}
protected:
HANDLE hMapping;
LPVOID pAddress;
DWORD dwAccess;
};
//==================================================================================================
// Define share mem key type & template name
#define SHARE_MEM_KEY_TYPE LPCTSTR
#define SHARE_MEM_TEMPLATE CShareMem_WinX
#define SHARE_MEM_KEY( name , key_1 , key_2 ) SHARE_MEM_KEY_TYPE name = TEXT( key_2 );
#else
//==================================================================================================
// System V : Share Memory Template
template< typename T > class CShareMem_SysV
{
public;
CShareMem_SysV( )
{
pAddress = NULL;
hMapping = -1;
nAccess = 0;
}
~CShareMem_SysV( )
{
Delete( );
}
public:
inline int Create( KeyT lpszName , size_t nLength )
{
// Check parameter
if( NULL != pAddress || -1 != hMapping ) return -1;
// Get share memory id
//int iFlags = SHM_R|SHM_W|IPC_CREAT|IPC_EXCL;
hMapping = shmget( Key , Length , IPC_CREAT );
if( -1 == hMapping ){ return -2; }
// Set access mode
//struct shmid_ds shmds;
//shmctl(hMapping , IPC_STAT , &shmds );
//shmds.shm_perm.mode |= 0x1B4; /* rw-rw-r-- */
//shmctl(hMapping , IPC_SET , &shmds );
// Attach share memory
pAddress = shmat( hMapping , 0 , 0 );
if( NULL != pAddress )
{
nAccess = -1;
return 0;
}
// Remove share memory id
int hShare = hMapping; hMapping = -1;
return shmctl( hShare , IPC_RMID , 0 );
}
inline int Delete( )
{
// Check parameter
if( NULL == pAddress || -1 == hMapping ) return -1;
if( -1 != nAccess ) { return Close( ); }
// Detech and remove share memory
shmdt( pAddress ) ; pAddress = NULL;
shmctl( hMapping , IPC_RMID , 0 );
hMapping = -1; nAccess = 0;
return 0;
}
inline int Open( KeyT Key , bool Write = false )
{
// Check parameter
if( NULL != pAddress || -1 != hMapping ) return -1;
// Open share memory
nAccess = Write ? SHM_R : SHM_R | SHM_W ;
hMapping = shmget( Key , 0 , nAccess );
if( -1 == hMapping ) { return -2; }
// Attach share memory
pAddress = shmat( hMapping , 0 , 0 );
return pAddress ? 0 : -3 ;
}
inline int Close( )
{
// Check Parameter
if( NULL == pAddress || -1 == hMapping ) return -1;
if( -1 == nAccess ) { return Delete( ); }
// Share memory detech
void * pAddr = pAddress; pAddress = NULL;
hMapping = -1; nAccess = 0;
return shmdt( pAddr );
}
inline void * Address()
{
return (void *)pAddress;
}
public:
static int Exists( KeyT Key )
{
return shmget( Key , 0 , SHM_R );
}
static int Remove( KeyT Key )
{
int hShare = shmget( Key , 0 , SHM_R | SHM_W );
if( -1 == hShare ){ return 0; }
return shmctl( hShare , IPC_RMID , 0 );
}
protected:
int nAccess;
int hMapping;
char * pAddress;
};
//==================================================================================================
// Define share mem key type & template name
#define SHARE_MEM_KEY_TYPE key_t
#define SHARE_MEM_TEMPLATE CShareMem_SysV
#define SHARE_MEM_KEY( name , key_1 , key_2 ) enum { name = key_1 };
#endif
//==================================================================================================
// Instance Template Class : ShareMemory
typedef SHARE_MEM_TEMPLATE< SHARE_MEM_KEY_TYPE > ShareMemory;