Windows 共享記憶體與旗標控制機制

服務端程式碼:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

#include <windows.h>#include <stdio.h>#include <string>#include "SharedMemLib.h"void main(void) { #define BUFFER_SIZE (32 * sizeof(char))#define MESSAGE_SIZE (BUFFER_SIZE - sizeof(DWORD)) SharedMemLib *worker = new SharedMemLib(); char *nameOfMem = "Emprogria"; if (worker->Create(nameOfMem, BUFFER_SIZE)) { if (worker->Alloc()) { char *message = (char *)malloc(MESSAGE_SIZE); ZeroMemory(message, BUFFER_SIZE); DWORD count = 0; CopyMemory(worker->Read(), &count, sizeof(DWORD)); while (TRUE) { DWORD OK = worker->Lock(1); if (OK != WAIT_FAILED) { char *p = (char *)worker->Read(); char *msg = p + sizeof(DWORD); if (memcmp(message, msg, MESSAGE_SIZE)) { count++; CopyMemory(p, &count, sizeof(DWORD)); CopyMemory(message, msg, MESSAGE_SIZE); printf("%02d> %s\n", count, message); } worker->Unlock(); } Sleep(1000); } free(message); worker->Free(); } worker->Close(); } else { printf("Create Error:%d\n", GetLastError()); } }

請求端程式碼:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

#include <windows.h>#include <stdio.h>#include "../SharedMemServer/SharedMemLib.h"void main(void) { #define BUFFER_SIZE (32 * sizeof(char))#define MESSAGE_SIZE (BUFFER_SIZE - sizeof(DWORD)) SharedMemLib *worker = new SharedMemLib(); const char* nameOfMem = "Emprogria"; if (worker->Open(nameOfMem)) { if (worker->Alloc()) { for (int i = 1; i <= 16; i++) { DWORD OK = worker->Lock(1); while (OK != WAIT_FAILED) { if (OK == WAIT_OBJECT_0) { void *p = worker->Read(); DWORD remoteCount; memcpy(&remoteCount, p, sizeof(DWORD)); char *message = (char *)malloc(MESSAGE_SIZE); ZeroMemory(message, MESSAGE_SIZE); snprintf(message, MESSAGE_SIZE, "Hello-%02d", (remoteCount)); worker->Write(message, MESSAGE_SIZE, sizeof(DWORD)); printf("%s\n", message); free(message); worker->Unlock(); break; } } Sleep(1000); } worker->Free(); } worker->Close(); } else { printf("Open Error:%d\n", GetLastError()); } }

程式庫程式碼 (.cpp):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

#include "SharedMemLib.h" SharedMemLib::SharedMemLib() { } SharedMemLib::~SharedMemLib() { } BOOL SharedMemLib::Create(const char* nameOfMem, DWORD sizeOfMem) { this->sizeOfMem = sizeOfMem; this->hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, this->sizeOfMem, nameOfMem); char nameOfSemaphore[64]; sprintf_s(nameOfSemaphore, "%s_S", nameOfMem); // ONLY SERVER and ONE CLIENT this->hSemaphore = CreateSemaphore( NULL, 0, 2, nameOfSemaphore); return (hMapFile != NULL && this->hSemaphore != NULL); } BOOL SharedMemLib::Open(const char* nameOfMem) { this->hMapFile = OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, nameOfMem); char nameOfSemaphore[64]; sprintf_s(nameOfSemaphore, "%s_S", nameOfMem); this->hSemaphore = OpenSemaphore( SEMAPHORE_ALL_ACCESS, FALSE, nameOfSemaphore); return (hMapFile != NULL && this->hSemaphore != NULL); } BOOL SharedMemLib::Alloc() { if (this->hMapFile == NULL) { return FALSE; } this->Mem = MapViewOfFile(this->hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, this->sizeOfMem); return (this->Mem != NULL); } void SharedMemLib::Free() { if (this->Mem != NULL) { UnmapViewOfFile(this->Mem); this->Mem = NULL; } } void SharedMemLib::Close() { if (this->hMapFile != NULL) { CloseHandle(this->hMapFile); this->hMapFile = NULL; } if (this->hSemaphore != NULL) { CloseHandle(this->hSemaphore); this->hSemaphore = NULL; } } void* SharedMemLib::Read() { return (this->Mem); } void SharedMemLib::Write(void* message, size_t messageLength, int startPosition) { char *p = (char *)this->Mem + startPosition * sizeof(char); CopyMemory(p,(void *)message, messageLength); } DWORD SharedMemLib::Lock(long waitSec) { if (this->hSemaphore == NULL) return FALSE; DWORD OK = WaitForSingleObject(this->hSemaphore, waitSec); if (OK != WAIT_OBJECT_0) printf("\tLock = %d\n", OK); return (OK); } BOOL SharedMemLib::Unlock() { if (this->hSemaphore == NULL) return FALSE; DWORD OK = ReleaseSemaphore(this->hSemaphore, 1, NULL); return (!OK); }

程式庫程式碼 (.h):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

#pragma once#include <windows.h>#include <stdio.h>#include <string>class SharedMemLib { private: HANDLE hMapFile = NULL; HANDLE hSemaphore = NULL; DWORD sizeOfMem; void *Mem = NULL; public: SharedMemLib(); ~SharedMemLib(); BOOL Create(const char* nameOfMem, DWORD sizeOfMem); BOOL Open(const char* nameOfMem); BOOL Alloc(); void Free(); void Close(); void* Read(); void Write(void* message, size_t messageLength, int startPosition); DWORD Lock(long waitSec=INFINITE); BOOL Unlock(); };

開發環境: