DLL1
DLL1は単純にユニット内でグローバル変数を宣言し、それをSetGRData()、 GetGRData()の2つのエクスポート関数によって、読み書きするためのDLLです。 本文にあるようにDLLを読込んだプロセス毎に prglobal1,unitglobal1の変数 領域が割り当てられます。
DLL1.dpr |
library DLL1; uses DLL1Main in 'DLL1Main.pas'; exports SetGRData, GetGRData; {$R *.RES} begin end. |
DLL1Main.pas |
unit DLL1Main; interface var prglobal1:integer; function SetGRData(V1,V2:integer):integer;export;stdcall; function GetGRData(Value:integer):integer;export;stdcall; implementation var unitglobal1:integer; function SetGRData(V1,V2:integer):integer;export;stdcall; begin prglobal1 := V1; unitglobal1 := V2; result := 0; end; function GetGRData(Value:integer):integer;export;stdcall; begin case Value Of 1: result := prglobal1; 2: result := unitglobal1; end; end; end. |
DLL2 [ → DLL1.source ]
メモリマップドファイルを使って変数を共有できるようにしたものです。エクスポート関数などの型はDLL1と一緒です。
DLL2.dpr |
library DLL2; uses DLL2Main in 'DLL2Main.pas'; exports SetGRData, GetGRData; {$R *.RES} begin end. |
DLL2-A
DLL2をすっきりさせたもの(MMFサンプルの最終形)。コードの見通しを良くするためにエラーに対してはほとんど考慮していません。上のDLL2Main.pasのコードに比べてすっきりしているのが分かると思います。実際に使う場合はGetFileMapObj(),ReleaseFileMapObj()でエラーハンドリングをするとか例外を発生させるなどして下さい。このサンプルではGetFileMapObj()でエラーが出るとマイナスを値を返すようにしています。呼び出し側では戻り値を使っていません。
DLL2AMain.pas |
unit DLL2AMain; interface uses Windows; type //共有データの構造体 TShareData = record data1:integer; data2:integer; end; pShareData = ^TShareData; function SetGRData(V1,V2:integer):integer;export;stdcall; function GetGRData(Value:integer):integer;export;stdcall; const //MMFに割り当てるユニークな文字列 uniqueString = 'This is Memory Mapped File Test!!!'; var hFMOBJ:THandle; implementation //MMFオープン、MMFビューの設定 function GetFileMapObj(var h: THandle; var ptr: Pointer):integer; begin //MMFをオープンする h := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, uniqueString); if h = 0 then begin result := -1; exit; end; //MMFビューの割り当て ptr := MapViewOfFile(_hFMOBJ, FILE_MAP_ALL_ACCESS, 0, 0, 0); if ptr = nil then begin result := -2; Exit; end; result := 0; end; //MMFビューの解除、MMFハンドルのクローズ function ReleaseFileMapObj(h: THandle; ptr: Pointer):integer; begin //ビューの開放 UnmapViewOfFile(ptr); //MMFを閉じる CloseHandle(h); result := 0; end; function SetGRData(V1,V2:integer):integer;export;stdcall; var _hFMOBJ:THandle; p:pointer; begin result := -1; GetFileMapObj(_hFMOBJ,p); //構造体にキャストしてデータにアクセス with pShareData(p)^ do begin data1 := V1; data2 := V2; end; ReleaseFileMapObj(_hFMOBJ, p); Result := hFMOBJ; end; function GetGRData(Value:integer):integer;export;stdcall; var _hFMOBJ:THandle; p:pointer; begin result := 0; GetFileMapObj(_hFMOBJ,p); //構造体をキャストしてデータにアクセス with pShareData(p)^ do case Value Of 1: result := Data1; 2: result := Data2; end; ReleaseFileMapObj(_hFMOBJ, p); end; //MMF初期化 initialization begin hFMOBJ := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TShareData), uniqueString); end; //MMFハンドル開放 finalization begin if hFMOBJ = 0 then exit; CloseHandle(hFMOBJ); end; end. |