• 简单小巧的跨平台共享内存代码


    如何使用的示例代码
        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;
  • 相关阅读:
    Metasploit advanced命令使用技巧
    Metasploit命令info使用技巧
    Kali Linux 2020.1b发布了
    设置USB无线网卡为监听模式大学霸IT达人
    解决ifconfig命令未找到
    Metasploit新增技巧提示功能
    Wireshark运算符!=无法正常工作
    解决Kali Linux XFCE桌面Tab无法补全
    Nessus更新到8.9.1
    ASP入门(七)-Response小案例
  • 原文地址:https://www.cnblogs.com/WonKerr/p/ShareMemory.html
Copyright © 2020-2023  润新知