zoukankan      html  css  js  c++  java
  • Delphi Memory-Mapped File简单示例

    {
    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.
    

      

  • 相关阅读:
    12月12日总结
    练习:请用索引取出下面list的指定元素:
    练习:小明身高1.75,体重80.5kg。请根据BMI公式(体重除以身高的平方)帮小明计算他的BMI指数,并根据BMI指数:
    练习:请利用循环依次对list中的每个名字打印出Hello, xxx!:
    练习:学员管理系统
    练习:请修改列表生成式,通过添加if语句保证列表生成式能正确地执行
    CF1067D Computer Game
    高等数学第三章
    CF755G PolandBall and Many Other Balls
    TS泛型工具
  • 原文地址:https://www.cnblogs.com/wucg/p/4263546.html
Copyright © 2011-2022 走看看