Windows uses file mapping to achieve shared memory

  
Windows using file mapping to achieve shared memory is relatively simple, the following is the implementation code, the details are explained with comments. Calling an operation similar to shm under Linux. This class has not been tested too much, welcome to ask questions and bugs ~~:)
#include <windows.h>#include <string>#include <iostream>#include <assert.h>using Std::string;using std::cout;using std::endl;#pragma warning(disable: 4311)class shareMemory{private: LPWSTR shm_name_u; bool is_create_file; void * sh_base; HANDLE semaphore; HANDLE file_mapping; int addr_len;public : /* create_file is used to indicate whether to use disk file mapping or page file mapping. If you use disk file mapping, shared memory will not have the problem of illegal access after memory release, but a file will be created on the disk, the file name will be The parameter shm_name is given. If you use page file mapping, a file will not be created on disk */shareMemory(const string& shm_name, bool create_file=false): is_create_file(create_file) { const char * _c_shm_name = shm_name.c_str(); int _size =( Sint_small_length. Sh_base = NULL; file_mapping = INVALID_HANDLE_VALUE; } void * shm_open(void* addr, const int length, DWORD protect) { addr_len = length; HANDLE _file_handle = INVALID_HANDLE_VALUE; if(is_create_file) { _file_handle= CreateFile(shm_name_u,GENERIC_READ|
 GENERIC_WRITE,0, NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);#ifdef _DEBUG if(_file_handle==INVALID_HANDLE_VALUE) cout<<"can not create file! we use page file instead!";#endif //end _DEBUG } /*Opens the file mapping of the specified name. If it does not exist, it creates a */file_mapping = OpenFileMapping(PAGE_READWRITE,false,shm_name_u ); if(file_mapping!=NULL) goto file_mapping_exist; file_mapping = CreateFileMapping(_file_handle,NULL,PAGE_READWRITE, 0, Length,shm_name_u);#ifdef _DEBUG assert(file_mapping);#endif if(file_mapping==NULL) return NULL;file_mapping_exist: sh_base = MapViewOfFileEx(file_mapping,protect,0,0,length,addr); CloseHandle(_file_handle); return Sh_base; } /*Write data to shared memory, return the number of bytes written out of data */int shm_write(void *dest, void * src, int size) { if(!check_adress(dest)) return -1; Int _write_count = (int)sh_base+addr_len - (int)dest; if(_write_count>size) _write_count = size;/*Using semaphor e Area for protection mapping (protected when different threads of the same process are called) */WaitForSingleObject(semaphore, INFINITE); memcpy(dest,src,_write_count); ReleaseSemaphore(semaphore,1,NULL); FlushViewOfFile(sh_base,_write_count ; return _write_count; } /* Read data from shared memory, return the number of data bytes read **/int shm_read(void* src, void * dest, int size) { if(!check_adress(src)) Return -1; int _read_count = (int)sh_base+addr_len -(int) src; if(_read_count>size) _read_count = size; memcpy(dest,src,_read_count); return _read_count; } ~shareMemory() { UnmapViewOfFile(sh_base ); free(shm_name_u); CloseHandle(semaphore); CloseHandle(file_mapping); }private :/* for address detection*/bool check_adress(void* addr) { if( ( (int)addr <(int)sh_base) |
 |
  ((int)addr > (int)sh_base+addr_len) ) { SetLastError(ERROR_ACCESS_DENIED);#ifdef _DEBUG printf("access denied,the destination address out of the map view!");#endif //_DEBUG return False; } return true; }};

Test: The main function of the write process:

int main(){ shareMemory sm("boost", false); void * bs = sm.shm_open( NULL, 1000*4, FILE_MAP_WRITE); if(bs==NULL) return -1; int a[10]; for(int i=0; i<10; ++i) a[i] = i; sm. Shm_write(bs,a,10*4); Sleep(100000);}The main function of the read process: 



int main(){ shareMemory sm("boost" , false); void * bs = sm.shm_open(NULL,1000,FILE_MAP_READ); if(bs==NULL) { cout<<"null"; return -1; } int b[10]; sm.shm_read (bs,b,10*4); for(int i=0; i<10; ++i) cout<b[i]<<" ";}
Copyright © Windows knowledge All Rights Reserved