tools
読み取り中…
検索中…
一致する文字列を見つけられません
connect.h
[詳解]
1#warning y9INC: This code has not been tested yet
2#pragma once
3#include <windows.h>
4#include <string>
5#include <stdexcept>
6
7/**
8 * @file connect.h
9 * @brief Windows 共有メモリ(名前付きファイルマッピング)通信クラス
10 *
11 * Windows の CreateFileMapping / OpenFileMapping API を使用して
12 * プロセス間共有メモリを確立し、任意の型のデータを読み書きします。
13 *
14 * @warning このコードはまだテストされていません (y9INC: This code has not been tested yet)
15 */
16
17/**
18 * @class PConnect
19 * @brief 名前付き共有メモリを介してプロセス間通信を行うテンプレートクラス
20 * @tparam T 共有するデータの型
21 *
22 * 2 つのコンストラクタで「作成モード」と「オープンモード」を区別します:
23 * - 作成モード: `PConnect(name, CREATEMODE___IMiNaSi)` → 共有メモリを新規作成
24 * - オープンモード: `PConnect(name)` → 既存の共有メモリに接続
25 *
26 * @code
27 * // プロセスA(作成側)
28 * PConnect<int> server("MySharedMem", 0);
29 * server.write(42);
30 *
31 * // プロセスB(接続側)
32 * PConnect<int> client("MySharedMem");
33 * int val = client.read(); // 42
34 * @endcode
35 */
36template<typename T>
37class PConnect {
38private:
39 HANDLE hMapFile; ///< 共有メモリのハンドル
40 T* pBuf; ///< マッピングされたメモリ(テンプレート型ポインタ)
41 std::string name; ///< 共有メモリの名前("Global\\" プレフィックス付き)
42
43public:
44 /**
45 * @brief 共有メモリを新規作成するコンストラクタ(作成モード)
46 * @param memName 共有メモリの名前("Global\\" が自動付加される)
47 * @param CREATEMODE___IMiNaSi 作成モードであることを示すダミー引数(値は使用しない)
48 * @throws std::runtime_error 共有メモリの作成またはマッピングに失敗した場合
49 */
50 PConnect(const std::string& memName, int8_t CREATEMODE___IMiNaSi)
51 : hMapFile(nullptr), pBuf(nullptr), name("Global\\"+memName) {
52 hMapFile = CreateFileMapping(
53 INVALID_HANDLE_VALUE, // 物理ファイルを使わない
54 NULL, // デフォルトのセキュリティ
55 PAGE_READWRITE, // 読み書き可能
56 0, // サイズ(高位)
57 sizeof(T), // サイズ(低位)
58 name.c_str() // 共有メモリの名前
59 );
60
61 if (hMapFile == NULL || hMapFile == INVALID_HANDLE_VALUE) {
62 DWORD errorCode = GetLastError();
63 std::cerr << "共有メモリ作成エラー: " << errorCode << " (" << PConnect::getLastErrorAsString() << ")" << std::endl;
64
65 if (errorCode == ERROR_ACCESS_DENIED) {
66 std::cerr << "解決策: 管理者権限を使用するか、共有メモリ名を確認してください。" << std::endl;
67 } else if (errorCode == ERROR_ALREADY_EXISTS) {
68 std::cerr << "解決策: 既存の共有メモリに接続するか、異なる名前を使用してください。" << std::endl;
69 } else {
70 std::cerr << "詳細なエラー内容を確認してください。" << std::endl;
71 }
72
73 throw std::runtime_error("共有メモリの作成に失敗しました。");
74 }
75
76 // メモリをプロセスにマッピング
77 pBuf = static_cast<T*>(MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, sizeof(T)));
78 if (!pBuf) {
79 CloseHandle(hMapFile);
80 throw std::runtime_error("共有メモリのマッピングに失敗しました");
81 }
82 }
83
84 /**
85 * @brief 既存の共有メモリに接続するコンストラクタ(オープンモード)
86 * @param memName 接続する共有メモリの名前("Global\\" が自動付加される)
87 * @throws std::runtime_error 共有メモリのオープンまたはマッピングに失敗した場合
88 */
89 PConnect(const std::string& memName)
90 : hMapFile(nullptr), pBuf(nullptr), name("Global\\"+memName) {
91 hMapFile = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, name.c_str());
92 if (!hMapFile) throw std::runtime_error("共有メモリのオープンに失敗しました");
93
94 pBuf = static_cast<T*>(MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, sizeof(T)));
95 if (!pBuf) {
96 CloseHandle(hMapFile);
97 throw std::runtime_error("共有メモリのマッピングに失敗しました");
98 }
99 }
100
101 /**
102 * @brief 共有メモリにデータを書き込む
103 * @param data 書き込むデータ(型 T)
104 * @throws std::runtime_error マッピングポインタが無効な場合
105 */
106 void write(const T& data) {
107 if (!pBuf) {
108 throw std::runtime_error("書き込み対象が無効です");
109 }
110 *pBuf = data;
111 }
112
113 /**
114 * @brief 共有メモリからデータを読み込む
115 * @return 共有メモリの現在値(型 T のコピー)
116 * @throws std::runtime_error マッピングポインタが無効な場合
117 */
118 T read() const {
119 if (!pBuf) {
120 throw std::runtime_error("読み込み対象が無効です");
121 }
122 return *pBuf;
123 }
124
125 /**
126 * @brief デストラクタ。マッピングとハンドルを解放する
127 */
129 if (pBuf) {
130 UnmapViewOfFile(pBuf);
131 }
132 if (hMapFile) {
133 CloseHandle(hMapFile);
134 }
135 }
136
137private:
138 /**
139 * @brief 最後の Windows エラーコードのメッセージ文字列を取得する
140 * @return エラーメッセージ文字列。エラーがない場合は "エラーは発生していません"
141 */
142 static std::string getLastErrorAsString() {
143 DWORD errorMessageID = ::GetLastError();
144 if (errorMessageID == 0) {
145 return "エラーは発生していません";
146 }
147
148 LPSTR messageBuffer = nullptr;
149
150 size_t size = FormatMessageA(
151 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
152 NULL,
153 errorMessageID,
154 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
155 (LPSTR)&messageBuffer,
156 0,
157 NULL);
158
159 std::string message(messageBuffer, size);
160
161 LocalFree(messageBuffer);
162
163 return message;
164 }
165};
~PConnect()
デストラクタ。マッピングとハンドルを解放する
Definition connect.h:128
PConnect(const std::string &memName, int8_t CREATEMODE___IMiNaSi)
共有メモリを新規作成するコンストラクタ(作成モード)
Definition connect.h:50
PConnect(const std::string &memName)
既存の共有メモリに接続するコンストラクタ(オープンモード)
Definition connect.h:89
void write(const T &data)
共有メモリにデータを書き込む
Definition connect.h:106
T read() const
共有メモリからデータを読み込む
Definition connect.h:118
size_t size(const std::string &input)
UTF-8 文字列のマルチバイト文字数(文字単位の長さ)を返す
Definition string.h:254