Delphi7 WindowsXP です。
CreateFileMappingを使って文字列やarrayなどは共有できるのですが、
TStringList の AddObject を使ったオブジェクトが取得できません。
同一プログラム内でMapViewOfFileを使うと取得できるのですが、
プログラムを二つ立ち上げて共有させようとすると何も取得できません。
CreateFileMappingでは出来ないのでしょうか?何か他の方法があるので
しょうか?サンプルを書いてみました。よろしくお願いします。
type
TData = class(TObject)
public
FData1 : String;
FData2 : String;
end;
TForm1 = class(TForm)
(略)
private
wStringList1 : TStringList;
public
end;
var
Form1: TForm1;
HFILE: THandle; // マッピングファイルオブジェクトのハンドル
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
wStringList1 := TStringList.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
idx : Integer;
begin
for idx := wStringList1.Count -1 downto 0 do
wStringList1.Objects[idx].Free;
wStringList1.Free;
CloseHandle( HFILE );
end;
procedure TForm1.Button1Click(Sender: TObject);
var
wData : TData;
idx : Integer;
begin
for idx := 0 to 10 do
begin
wData := TData.Create;
wData.FData1 := Format('%8.8d',[idx]);
wData.FData2 := Format('%8.8d',[idx*10]);
wStringList1.AddObject(wData.FData1,wData);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
idx : Integer;
begin
for idx := 0 to wStringList1.Count-1 do
with TData(wStringList1.Objects[idx]) do
ListBox1.Items.Add(FData1+'|'+FData2);
end;
procedure TForm1.Button3Click(Sender: TObject);
var
P1 : Pointer;
begin
HFILE := CreateFileMapping( $FFFFFFFF, nil, PAGE_READWRITE,
0, SizeOf(wStringList1), '_FileMappingTest' );
if HFILE <> 0 then
begin
P1 := MapViewOfFile( HFILE, FILE_MAP_WRITE, 0, 0, 0 );
if P1 <> nil then
begin
CopyMemory( P1, @wStringList1, SizeOf(wStringList1) );
UnmapViewOfFile( P1 );
end;
end;
end;
procedure TForm1.Button4Click(Sender: TObject);
var
HF : THandle;
P2 : Pointer;
ST : TStringList;
idx : Integer;
begin
HF := OpenFileMapping( FILE_MAP_READ, False, '_FileMappingTest' );
if HF <> 0 then
begin
P2 := MapViewOfFile( HF, FILE_MAP_READ, 0, 0, 0 );
if P2 <> nil then
begin
CopyMemory( @ST, P2, SizeOf( ST )); //ClassはTStringListに
UnmapViewOfFile( P2 ); //なってくれている
for idx := 0 to ST.Count -1 do //ST.Count が 0 になる
begin
with TData(ST.Objects[idx]) do
begin
ListBox2.Items.Add(FData1 + '|' + FData2);
end;
end;
end;
end;
end;
オブジェクト参照はポインタです。共有メモリを使って正しく参照を渡せたとしても、
それを使うことはできません。オブジェクトの本体を渡せないのですから。
通りすがりさんありがとうございます。
やはりオブジェクトの本体は渡せないですよね。
DBのマスター系をメモリに持ってプログラムごとDB参照するのを
止めようかと思って考えてました。
ありがとうございました。
ツイート | ![]() |