TNB Library
TnbSharedMemory.h
[詳解]
1#pragma once
13#include "TnbDef.h"
14
15
16
17//TNB Library
18namespace TNB
19{
20
21
22
35{
36//protected:
37 HANDLE m_hFileMap;
38 LPVOID m_lpvMapAdds;
39 bool m_boCanClose;
40public:
41
47 explicit CSharedMemoryManager(bool boCanClose = false)
48 {
49 m_lpvMapAdds = NULL;
50 m_hFileMap = NULL;
51 m_boCanClose = boCanClose;
52 }
53
56 {
57 if ( m_boCanClose )
58 {
59 Close();
60 }
61 else
62 {
63 if ( m_lpvMapAdds != NULL )
64 {
65 ::UnmapViewOfFile(m_lpvMapAdds);
66 }
67 }
68 };
69
75 bool HasMemory(void)
76 {
77 return Get() != NULL;
78 }
79
86 LPVOID Get(void)
87 {
88 if ( m_lpvMapAdds != NULL )
89 {
90 // このクラスの共有メモリはすでにオープンしている
91 return m_lpvMapAdds;
92 }
93 return NULL;
94 }
95
105 int Open(LPCTSTR lpszMemName, UINT uMemSize)
106 {
107 if ( m_lpvMapAdds != NULL )
108 {
109 // このクラスの共有メモリはすでにオープンしている
110 Close();
111 }
112 // 共有メモリハンドルオープン
113 m_hFileMap = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, uMemSize, lpszMemName);
114 if ( m_hFileMap != NULL )
115 {
116 // 共有メモリオープン成功!
117 DWORD dwError = ::GetLastError();
118 // マッピングする。
119 m_lpvMapAdds = ::MapViewOfFile(m_hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
120 if ( m_lpvMapAdds != NULL )
121 {
122 return (dwError == ERROR_ALREADY_EXISTS) ? 1/*既存*/ : 0/*新規*/;
123 }
124 // マッピング失敗
125 _GetLastError("MapViewOfFile");
126 ::CloseHandle(m_hFileMap); // ハンドルを閉じなくては
127 m_lpvMapAdds = NULL;
128 }
129 else
130 {
131 // 共有メモリオープン失敗
132 _GetLastError("CreateFileMapping");
133 m_lpvMapAdds = NULL;
134 }
135 return -1;
136 }
137
144 bool Close(void)
145 {
146 if ( m_lpvMapAdds == NULL )
147 {
148 // 開いていなかった(未使用だった)
149 return true;
150 }
151 if ( ! ::UnmapViewOfFile(m_lpvMapAdds) )
152 {
153 //アンマップド失敗
154 return false;
155 }
156 m_lpvMapAdds = NULL;
157 if ( m_hFileMap != 0 ) //念のためチェック
158 {
159 if ( ! ::CloseHandle(m_hFileMap) )
160 {
161 //ハンドルがクローズできなかった
162 return false;
163 }
164 }
165 return true;
166 }
167};
168
169
170
213template<typename TYP>
215{
216 CSharedMemoryManager m_cSharedMem;
217 TYP* m_pType;
218 bool m_boCanClose;
219
220public:
221
236 {
238 virtual ~IListener(void) {}
239
246 virtual void OnAction(TYP* P) = 0;
247 };
248
261 explicit CSharedStructT(bool boCanClose = true) : m_cSharedMem(boCanClose)
262 {
263 m_boCanClose = boCanClose;
264 m_pType = NULL;
265 }
266
268 virtual ~CSharedStructT(void)
269 {
270 Close();
271 }
272
278 bool HasMemory(void) const
279 {
280 return m_pType != NULL;
281 }
282
288 operator TYP*(void)
289 {
290 return m_pType;
291 }
292
298 operator const TYP*(void) const
299 {
300 return m_pType;
301 }
302
308 TYP* operator->(void)
309 {
310 return m_pType;
311 }
312
318 const TYP* operator->(void) const
319 {
320 return m_pType;
321 }
322
336 bool Open(LPCTSTR lpMemName = NULL, IListener* piListener = NULL)
337 {
338 int iRc = m_cSharedMem.Open(lpMemName, sizeof(LONG) * 2 + sizeof(TYP));
339 if ( iRc < 0 )
340 {
341 return false;
342 }
343 LONG* P = static_cast<LONG*>(m_cSharedMem.Get());
344 m_pType = reinterpret_cast<TYP*>(&P[2]);
345 if ( iRc == 0 )
346 {
347 //==新規
348 if ( piListener != NULL )
349 {
350 piListener->OnAction(m_pType);
351 }
352 P[1]++; //参照カウンタ
353 P[0] = 1; //初期化済み
354 }
355 else
356 {
357 //==既存
358 while ( P[0] != 1 )
359 {
360 ::Sleep(1);
361 }
362 P[1]++; //参照カウンタ
363 }
364 return true;
365 }
366
373 void Close(IListener* piListener = NULL)
374 {
375 LONG* P = static_cast<LONG*>(m_cSharedMem.Get());
376 if ( P == NULL ){ return; }
377 while ( true )
378 {
379 while ( P[0] != 1 )
380 {
381 ::Sleep(1);
382 }
383 if ( ::InterlockedDecrement(&P[0]) == 0 )
384 {
385 break;
386 }
387 }
388 if ( ::InterlockedDecrement(&P[1]) <= 0 )
389 {
390 //最後の一つ
391 if ( piListener != NULL )
392 {
393 piListener->OnAction(m_pType);
394 }
395 if ( ! m_boCanClose )
396 {
397 //閉じない、だからカウンタは1のままに
398 P[1] = 1;
399 }
400 P[0] = 1;
401 if ( m_boCanClose )
402 {
403 //閉じる
404 m_cSharedMem.Close();
405 }
406 }
407 else
408 {
409 P[0] = 1;
410 m_cSharedMem.Close();
411 }
412 m_pType = NULL;
413 }
414};
415
416
417
418}; // TNB
TNBライブラリの定義ヘッダ
[ETC] コピー不可能スーパークラス.
Definition: TnbDef.h:599
簡易共有メモリ管理クラス
bool Close(void)
[操作] クローズ.
CSharedMemoryManager(bool boCanClose=false)
コンストラクタ
LPVOID Get(void)
[取得] アドレス参照.
bool HasMemory(void)
[確認] 共有メモリの有無
virtual ~CSharedMemoryManager(void)
デストラクタ
int Open(LPCTSTR lpszMemName, UINT uMemSize)
[操作] オープン
共有構造体管理テンプレート
void Close(IListener *piListener=NULL)
[操作] クローズ
bool HasMemory(void) const
[確認] 共有メモリの有無
virtual ~CSharedStructT(void)
デストラクタ
const TYP * operator->(void) const
[取得] メモリの参照.
bool Open(LPCTSTR lpMemName=NULL, IListener *piListener=NULL)
[操作] オープン
CSharedStructT(bool boCanClose=true)
コンストラクタ
TYP * operator->(void)
[取得] メモリの参照.
TNB Library
Definition: TnbDoxyTitle.txt:2
共有構造体管理のリスナーインターフェース
virtual ~IListener(void)
デストラクタ
virtual void OnAction(TYP *P)=0
[通知] アクション発生