メモリマップドファイルを使うと、アプリケーション間でデータを共有することができます。
※サンプルプログラムでは、プロジェクトの設定で「_TCHARのマップ先」を「wchar_t」にしています。
フォームに次のコントロールを配置します。
フォームのprivateに次の2つのメンバ変数を設定します。
ヘッダファイルは次のようになります。
class TForm1 : public TForm
{
__published: // IDE 管理のコンポーネント
TButton *Button1;
TMemo *Memo1;
TEdit *Edit1;
private: // ユーザー宣言
HANDLE FMapFile;
LPTSTR FMapAdderss;
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
};
フォームのコンストラクタでメモリマップドファイルを作成します。
ファイルマッピングオブジェクトの最大サイズとオブジェクト名を設定します。
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//ファイルマッピングオブジェクトを作成する
FMapFile = CreateFileMapping(
(HANDLE)INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0, // サイズを表す上位 DWORD
1024, // サイズを表す下位 DWORD
L"FileMappingSample"); //ファイルマッピングオブジェクトの名前
//ファイルマッピングオブジェクトの作成に失敗したとき
if (FMapFile == NULL) {
Memo1->Lines->Add(L"ファイルマッピングオブジェクトの作成に失敗しました。");
}
}
フォーム破棄するときに使用しているメモリとハンドルを破棄します。
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
//ファイルのマップトビューをアンマップする
UnmapViewOfFile(FMapAdderss);
//ファイルマッピングオブジェクトのハンドルを解放する
CloseHandle(FMapFile);
}
「送出」ボタンを押すと、メモリマップドファイルにデータを書き込みます。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//ファイルマッピングオブジェクトに失敗したとき
if (!FMapFile) return;
//アドレス空間にファイルのビューをマップする
FMapAdderss = (LPTSTR)MapViewOfFile(FMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
if (FMapAdderss == NULL) {
Memo1->Lines->Add(L"マップに失敗しました。");
return;
}
//データを書き込む
lstrcpyn(FMapAdderss, Edit1->Text.c_str(), 1024 / sizeof(TCHAR));
//フラッシュして確実に更新する
FlushViewOfFile(FMapAdderss, _tcslen(FMapAdderss));
Memo1->Lines->Add(L"マップしました。");
}
フォームに次のコントロールを配置します。
「受取」ボタンを押すと、メモリマップドファイルからデータを読み込みます。
void __fastcall TForm2::Button1Click(TObject *Sender)
{
//名前付きのファイルマッピングオブジェクトを開く
HANDLE mapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, L"FileMappingSample");
if (mapFile == NULL) {
Memo1->Lines->Add(L"ファイルマッピングオブジェクトを開けません。");
return;
}
//アドレス空間にファイルのビューをマップする
LPTSTR mapAdderss = (LPTSTR)MapViewOfFile(mapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (mapAdderss == NULL) {
Memo1->Lines->Add(L"取得に失敗しました。");
return;
}
//読み込み
Memo1->Lines->Add(mapAdderss);
//ファイルのマップトビューをアンマップする
UnmapViewOfFile(mapAdderss);
//ファイルマッピングオブジェクトのハンドルを解放する
CloseHandle(FMapFile);
}
以上で、データの共有ができるようになりました。
メモリマップドファイルに対して同時に読み書きが行われると、データの状態が正しくなくなる可能性があります。
ミューテックスを使用して、同期をとるようにします。
class TForm1 : public TForm
{
__published: // IDE 管理のコンポーネント
TButton *Button1;
TLabeledEdit *Edit1;
TMemo *Memo1;
void __fastcall FormDestroy(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
private: // ユーザー宣言
HANDLE FMapFile;
HANDLE FMutex;
LPTSTR FMapAdderss;
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
};
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//ファイルマッピングオブジェクトを作成する
FMapFile = CreateFileMapping(
(HANDLE)INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0, // サイズを表す上位 DWORD
1024, // サイズを表す下位 DWORD
L"FileMappingSample"); //ファイルマッピングオブジェクトの名前。
//ファイルマッピングオブジェクトの作成に失敗したとき
if (FMapFile == NULL) {
Memo1->Lines->Add(L"ファイルマッピングオブジェクトの作成に失敗しました。");
}
//ミューテックスオブジェクトを作成する
FMutex = CreateMutex(NULL, FALSE, L"MutexSample");
//ミューテックスオブジェクトの作成に失敗したとき
if (FMutex == NULL) {
Memo1->Lines->Add(L"ミューテックスオブジェクトの作成に失敗しました。");
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
//ファイルのマップトビューをアンマップする
UnmapViewOfFile(FMapAdderss);
//ファイルマッピングオブジェクトのハンドルを解放する
CloseHandle(FMapFile);
//ミューテックスオブジェクトのハンドルを解放する
CloseHandle(FMutex);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//ファイルマッピングオブジェクトに失敗したとき
if (!FMapFile) return;
//アドレス空間にファイルのビューをマップする
FMapAdderss = (LPTSTR)MapViewOfFile(FMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
if (FMapAdderss == NULL) {
Memo1->Lines->Add(L"マップに失敗しました。");
return;
}
//ミューテックスオブジェクトの状態をチェックする
WaitForSingleObject(FMutex, INFINITE);
//データを書き込む
lstrcpyn(FMapAdderss, Edit1->Text.c_str(), 1024 / sizeof(TCHAR));
//フラッシュして確実に更新する
FlushViewOfFile(FMapAdderss, _tcslen(FMapAdderss));
//ミューテックスオブジェクトの所有権を解放する
ReleaseMutex(FMutex);
Memo1->Lines->Add(L"マップしました。");
}
void __fastcall TForm2::Button1Click(TObject *Sender)
{
//名前付きのファイルマッピングオブジェクトを開く
HANDLE mapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, L"FileMappingSample");
if (mapFile == NULL) {
Memo1->Lines->Add(L"ファイルマッピングオブジェクトを開けません。");
return;
}
//ミューテックスオブジェクトを作成する
HANDLE mutex = CreateMutex(NULL, FALSE, L"MutexSample");
if (mutex == NULL) {
Memo1->Lines->Add(L"ミューテックスオブジェクトの作成に失敗しました。");
}
//ミューテックスオブジェクトの状態をチェックする
WaitForSingleObject(mutex, INFINITE);
//アドレス空間にファイルのビューをマップする
LPTSTR mapAdderss = (LPTSTR)MapViewOfFile(mapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (mapAdderss == NULL) {
Memo1->Lines->Add(L"取得に失敗しました。");
return;
}
//読み込み
Memo1->Lines->Add(mapAdderss);
//ミューテックスオブジェクトの所有権を解放する
ReleaseMutex(mutex);
//ミューテックスオブジェクトのハンドルを解放する
CloseHandle(mutex);
//ファイルのマップトビューをアンマップする
UnmapViewOfFile(mapAdderss);
//ハンドルを解放する
CloseHandle(mapFile);
}