Delphi Memory-Mapped File의 간단한 예
10157 단어 Delphi
{
Copyright ?1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
const
FName = 'test.txt';
type
TMainForm = class(TForm)
btnUpperCase: TButton;
memTextContents: TMemo;
lblContents: TLabel;
btnLowerCase: TButton;
procedure btnUpperCaseClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnLowerCaseClick(Sender: TObject);
public
UCase: Boolean;
procedure ChangeFileCase;
end;
var
MainForm: TMainForm;
implementation
{$R *.DFM}
procedure TMainForm.btnUpperCaseClick(Sender: TObject);
begin
UCase := True;
ChangeFileCase;
end;
procedure TMainForm.btnLowerCaseClick(Sender: TObject);
begin
UCase := False;
ChangeFileCase;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
memTextContents.Lines.LoadFromFile(FName);
// Change to upper case by default.
UCase := True;
end;
procedure TMainForm.ChangeFileCase;
var
FFileHandle: THandle; // Handle to the open file.
FMapHandle: THandle; // Handle to a file-mapping object
FFileSize: Integer; // Variable to hold the file size.
FData: PByte; // Pointer to the file's data when mapped.
PData: PChar; // Pointer used to reference the file data.
begin
{ First obtain a file handle to the file to be mapped. This code
assumes the existence of the file. Otherwise, you can use the
FileCreate() function to create a new file. }
if not FileExists(FName) then
raise Exception.Create('File does not exist.')
else
FFileHandle := FileOpen(FName, fmOpenReadWrite);
// If CreateFile() was not successful, raise an exception
if FFileHandle = INVALID_HANDLE_VALUE then
raise Exception.Create('Failed to open or create file');
try
{ Now obtain the file size which we will pass to the other file-
mapping functions. We'll make this size one byte larger as we
need to append a null-terminating character to the end of the
mapped-file's data.}
FFileSize := GetFileSize(FFileHandle, Nil);
{ Obtain a file-mapping object handle. If this function is not
successful, then raise an exception. }
FMapHandle := CreateFileMapping(FFileHandle, nil,
PAGE_READWRITE, 0, FFileSize, nil);
if FMapHandle = 0 then
raise Exception.Create('Failed to create file mapping');
finally
// Release the file handle
CloseHandle(FFileHandle);
end;
try
{ Map the file-mapping object to a view. This will return a pointer
to the file data. If this function is not successful, then raise
an exception. }
FData := MapViewOfFile(FMapHandle, FILE_MAP_ALL_ACCESS, 0, 0, FFileSize);
if FData = Nil then
raise Exception.Create('Failed to map view of file');
finally
// Release the file-mapping object handle
CloseHandle(FMapHandle);
end;
try
{ !!! Here is where you would place the functions to work with
the mapped file's data. For example, the following line forces
all characters in the file to uppercase }
PData := PChar(FData);
// Position the pointer to the end of the file's data
inc(PData, FFileSize);
// Append a null-terminating character to the end of the file's data
PData^ := #0;
// Now set all characters in the file to uppercase
if UCase then
StrUpper(PChar(FData))
else
StrLower(PChar(FData));
finally
// Release the file mapping.
UnmapViewOfFile(FData);
end;
memTextContents.Lines.Clear;
memTextContents.Lines.LoadFromFile(FName);
end;
end.
Using a DLL with Shared Memory
//ShareLib.dpr
{
Copyright ?1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}
library ShareLib;
uses
ShareMem,
Windows,
SysUtils,
Classes;
const
cMMFileName: PChar = 'SharedMapData';
{$I DLLDATA.INC}
var
GlobalData : PGlobalDLLData;
MapHandle : THandle;
{ GetDLLData will be the exported DLL function }
procedure GetDLLData(var AGlobalData: PGlobalDLLData); StdCall;
begin
{ Point AGlobalData to the same memory address referred to by GlobalData. }
AGlobalData := GlobalData;
end;
procedure OpenSharedData;
var
Size: Integer;
begin
{ Get the size of the data to be mapped. }
Size := SizeOf(TGlobalDLLData);
{ Now get a memory-mapped file object. Note the first parameter passes
the value $FFFFFFFF or DWord(-1) so that space is allocated from the system's
paging file. This requires that a name for the memory-mapped
object get passed as the last parameter. }
MapHandle := CreateFileMapping(DWord(-1), nil, PAGE_READWRITE, 0, Size, cMMFileName);
if MapHandle = 0 then
RaiseLastWin32Error;
{ Now map the data to the calling process's address space and get a
pointer to the beginning of this address }
GlobalData := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, Size);
{ Initialize this data }
GlobalData^.S := 'ShareLib';
GlobalData^.I := 1;
if GlobalData = nil then
begin
CloseHandle(MapHandle);
RaiseLastWin32Error;
end;
end;
procedure CloseSharedData;
{ This procedure un-maps the memory-mapped file and releases the memory-mapped
file handle }
begin
UnmapViewOfFile(GlobalData);
CloseHandle(MapHandle);
end;
procedure DLLEntryPoint(dwReason: DWord);
begin
case dwReason of
DLL_PROCESS_ATTACH: OpenSharedData;
DLL_PROCESS_DETACH: CloseSharedData;
end;
end;
exports
GetDLLData;
begin
{ First, assign the procedure to the DLLProc variable }
DllProc := @DLLEntryPoint;
{ Now invoke the procedure to reflect that the DLL is attaching
to the process }
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
App1:
//App1.dpr
{
Copyright ?1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}
unit MainFrmA1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, ExtCtrls, Mask;
{$I DLLDATA.INC}
type
TMainForm = class(TForm)
edtGlobDataStr: TEdit;
btnGetDllData: TButton;
meGlobDataInt: TMaskEdit;
procedure btnGetDllDataClick(Sender: TObject);
procedure edtGlobDataStrChange(Sender: TObject);
procedure meGlobDataIntChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
public
GlobalData: PGlobalDLLData;
end;
var
MainForm: TMainForm;
{ Define the DLL's exported procedure }
procedure GetDLLData(var AGlobalData: PGlobalDLLData); StdCall External 'SHARELIB.DLL';
implementation
{$R *.DFM}
procedure TMainForm.btnGetDllDataClick(Sender: TObject);
begin
{ Get a pointer to the DLL's data }
GetDLLData(GlobalData);
{ Now update the controls to reflect GlobalData's field values }
edtGlobDataStr.Text := GlobalData^.S;
meGlobDataInt.Text := IntToStr(GlobalData^.I);
end;
procedure TMainForm.edtGlobDataStrChange(Sender: TObject);
begin
{ Update the DLL data with the changes }
GlobalData^.S := edtGlobDataStr.Text;
end;
procedure TMainForm.meGlobDataIntChange(Sender: TObject);
begin
{ Update the DLL data with the changes }
if meGlobDataInt.Text = EmptyStr then
meGlobDataInt.Text := '0';
GlobalData^.I := StrToInt(meGlobDataInt.Text);
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
btnGetDllDataClick(nil);
end;
end.
App2:
//App2.dpr
{
Copyright ?1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}
unit MainFrmA2;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;
{$I DLLDATA.INC}
type
TMainForm = class(TForm)
lblGlobDataStr: TLabel;
tmTimer: TTimer;
lblGlobDataInt: TLabel;
procedure tmTimerTimer(Sender: TObject);
public
GlobalData: PGlobalDLLData;
end;
{ Define the DLL's exported procedure }
procedure GetDLLData(var AGlobalData: PGlobalDLLData); StdCall External 'SHARELIB.DLL';
var
MainForm: TMainForm;
implementation
{$R *.DFM}
procedure TMainForm.tmTimerTimer(Sender: TObject);
begin
GetDllData(GlobalData); // Get access to the data
{ Show the contents of GlobalData's fields.}
lblGlobDataStr.Caption := GlobalData^.S;
lblGlobDataInt.Caption := IntToStr(GlobalData^.I);
end;
end.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Delphi] TStringBuilder그리고 꼭 사용해야만 할까? 그림처럼 Heap 영역에 "Hello" 공간을 생성하고 포인팅을 한다. "Hello World" 공간을 새로 생성한 후 포인팅을 하게 된다. 결국 "Hello" 라는 String 객체가 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.