プロセス間でデータの受け渡しをする際には、イロイロと方法があるようですが
今回は共有メモリ(メモリマップドファイル or メモリマップトファイル)を試してみます。
なにが出来るかというと、xxx.exeとyyy.exeがあったとして
xxx.exeのデータを共有メモリに書き込んで、yyy.exeから読み込めるという事です。
では、試す為には2つの.exeを作成しなければなりません。
今回は、書込側:Shared01.exe 読込側:Shared02.exe で実施します。
←Shared01.exe(書込側)のフォームはこんな感じです。
書込みボタンを押すと
エディットボックスに表示されている文字列を
共有メモリに書き込みます。
←Shared02.exe(読込側)のフォームはこんな感じです。
読込ボタンを押すと
共有メモリのデータをエディットボックスに表示します。
<Shared01.exe(書込側) | Unit1.h>
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE 管理のコンポーネント
TEdit *Edit1;
TButton *Button1;
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
void __fastcall Button1Click(TObject *Sender);
private: // ユーザー宣言
HANDLE m_hMapping;
// 共有メモリ作成
void __fastcall SharedMem_Create(AnsiString shd_name);
// 共有メモリ追加
void __fastcall SharedMem_Append(AnsiString shd_name, AnsiString shd_data);
// 共有メモリ削除
void __fastcall SharedMem_Delete(void);
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
<Shared01.exe(書込側) | Unit1.cpp>
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
// フォームが閉じた時呼ばれるイベント
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
// 共有メモリ削除
SharedMem_Delete();
}
//---------------------------------------------------------------------------
// 共有メモリへ書込ボタン
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString shd_name = "shared_test";
// 共有メモリ作成
SharedMem_Create(shd_name);
// 共有メモリ追加
SharedMem_Append(shd_name, Edit1->Text);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 共有メモリ作成
void __fastcall TForm1::SharedMem_Create(AnsiString shd_name)
{
// 共有メモリ(メモリマップトファイル)作成
m_hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE, // 読書き両方にする
0,
512, // 上限サイズを512byte設定
shd_name.c_str()// 共有メモリ名を設定
);
if ( m_hMapping == NULL ) {
ShowMessage("共有メモリ作成失敗");
return;
}
// マッピング開始
char *dat = (char *)MapViewOfFile(m_hMapping,
FILE_MAP_ALL_ACCESS, // 読書き両方
0,
0,
512); // 上限サイズは512byte
// 0クリアで初期化
ZeroMemory(dat, 512);
// マッピング解除
UnmapViewOfFile(dat);
}
//---------------------------------------------------------------------------
// 共有メモリ追加
void __fastcall TForm1::SharedMem_Append(AnsiString shd_name, AnsiString shd_data)
{
HANDLE hMapping = OpenFileMapping(FILE_MAP_WRITE, // 書込みモード
FALSE,
shd_name.c_str()); // 共有メモリ名指定
if ( hMapping == NULL ) {
ShowMessage("共有メモリが見つかりません");
return;
}
// マッピング開始
char *dat = (char *)MapViewOfFile(hMapping,
FILE_MAP_WRITE, // 書込で開始
0,
0,
512); // 上限サイズは512byte
// データ書き込み
strcpy(dat, shd_data.c_str());
// マッピング解除
UnmapViewOfFile(dat);
}
//---------------------------------------------------------------------------
// 共有メモリ削除
void __fastcall TForm1::SharedMem_Delete(void)
{
CloseHandle(m_hMapping);
m_hMapping = NULL;
}
//---------------------------------------------------------------------------
<Shared02.exe(読込側) | Unit1.h>
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE 管理のコンポーネント
TEdit *Edit1;
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);
private: // ユーザー宣言
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
<Shared02.exe(読込側) | Unit1.cpp>
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
// 共有メモリから読込ボタン
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// 共有メモリ(メモリマップトファイル)を開く
HANDLE hMapping = OpenFileMapping(FILE_MAP_READ, FALSE, "shared_test");
if ( hMapping == NULL ) {
ShowMessage("共有メモリが見つかりません");
return;
}
// マッピング開始
char *dat = (char *)MapViewOfFile(hMapping,
FILE_MAP_READ, // 読込モード
0,
0,
0); // 上限まで読込
if ( dat == NULL ) {
ShowMessage("共有メモリのデータがありません");
return;
}
// データ読込
Edit1->Text = AnsiString(dat);
// マッピング解除
UnmapViewOfFile(dat);
}
//---------------------------------------------------------------------------
Shared01.exeの書込みボタンから「レッツ共有!」という文字列を
共有メモリに書き込んでから、Shared02.exeの読込ボタンで読み込むと、
「レッツ共有!」が表示されます。
ちなみに、
上の例ではchar *ですが、構造体なんかでも問題なしです。