> Muxa/Ibl4 (21.07.09 22:33)
[17] Лови, я сегодня добрый. И давно на Delphi не писал, соскучился даже - вот и захотелось размяться слегка. Писал в Delphi 7.
Только не копируй бездумно - разберись в каждой строчке и в каждой букве - что она делает, зачем она это делает, как она это делает и почему она это делает именно тут, а не в другом месте. Справка и MSDN тебе в помощь, там все описано. А что останется неясным - спрашивай здесь.
1. Полный код общего юнита (используется и в DLL, и в тестовой программе)
unit DataType;
interface
type
TData = packed record
Int: integer;
Str: ShortString
end;
PData = ^TData;
TWriteData = procedure(Source: PData); stdcall;
TReadData = function: PData; stdcall;
const
DLL_NAME = 'MMF_DLL';
ReadDataProcName = 'ReadData';
WriteDataProcName = 'WriteData';
implementation
end.
2. Полный код DLL
library MMF_DLL;
uses
Windows,
SysUtils,
DataType in 'DataType.pas';
const
MMF_NAME = 'MySharedData';
var
HData: THandle = 0;
DataPtr: PData = nil;
procedure EntryProc;
begin
HData := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TData), MMF_NAME);
Win32Check(HData <> 0);
DataPtr := MapViewOfFile(HData, FILE_MAP_ALL_ACCESS, 0, 0, 0);
Win32Check(DataPtr <> nil)
end;
procedure ExitProc;
begin
UnmapViewOfFile(DataPtr);
CloseHandle(HData)
end;
procedure MyDllProc(Reason: integer);
begin
case Reason of
DLL_PROCESS_ATTACH: EntryProc;
DLL_PROCESS_DETACH: ExitProc
end
end;
procedure WriteData(Source: PData); stdcall;
begin
DataPtr^ := Source^
end;
function ReadData: PData; stdcall;
begin
Result := DataPtr
end;
exports
ReadData name ReadDataProcName,
WriteData name WriteDataProcName;
begin
if @DllProc = nil then
DllProc := MyDllProc;
MyDllProc(DLL_PROCESS_ATTACH)
end.
3. Код главной формы тестовой программы (на форму бросить 2 кнопки и назначить им OnClick)
uses
DataType;
var
Data: TData;
HLib: THandle = 0;
ReadData: TReadData = nil;
WriteData: TWriteData = nil;
procedure TForm1.FormCreate(Sender: TObject);
begin
HLib := LoadLibrary(DLL_NAME);
Win32Check(HLib <> 0);
@ReadData := GetProcAddress(HLib, ReadDataProcName);
Win32Check(@ReadData <> nil);
@WriteData := GetProcAddress(HLib, WriteDataProcName);
Win32Check(@WriteData <> nil);
Randomize
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeLibrary(HLib)
end;
procedure TForm1.ReadButtonClick(Sender: TObject);
begin
Data := ReadData^;
Caption := Format('Прочитано: < %d %s >', [Data.Int, Data.Str])
end;
procedure TForm1.WriteButtonClick(Sender: TObject);
begin
Data.Int := Random(10);
if Data.Int > 4 then
Data.Str := 'Привет Богам!'
else
Data.Str := 'А DLL-то одна!';
WriteData(@Data);
Caption := Format('Записано: < %d %s >', [Data.Int, Data.Str])
end;
4. Что с этим делать.Вначале все компилируем в один каталог (любой). Потом запускаем 2 копии тестовой программы и в обоих жмем кнопки Write и Read. Убеждаемся, что каждая программа читает из MMF точно то, что перед этим в MMF записала либо она сама же, либо другая программа.
PS
И богам своим покажи. Решение они приняли, панимашь... обхохотаться можно над такими решениями.