⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fastsharemem.pas

📁 由delphi实现的bt下载器示例程序
💻 PAS
字号:
unit FastShareMem;

(*
 * Shared Memory Allocator for Delphi DLL's
 * Version: 1.2
 *
 * Features:
 *   no runtime dll required.
 *   no performance degradation.
 *
 * Usage:
 *   Must be the first unit listed in the project file's USES section
 *   for both dll and exe projects. If you install a memory manager for
 *   leak detection, it should be listed immediately after this unit.
 *
 * Author: Emil M. Santos
 *   You may use and modify this software as you wish, but this section
 *   must be kept intact. Please see Readme.txt for copyright and disclaimer.
 *
 * Send bugs/comments to fastsharemem@codexterity.com
 * On the web: http://www.codexterity.com
 * To be notified of new versions by email, subscribe to the site alerter facility.

   Revision History:
   2002 Sep  9: Thanks to Ai Ming (aiming@ynxx.com) for these changes:
   				Modified to work with Windows NT/2000/XP.
   				Added reference-counting mechanism.
   2002 Aug 14: Rewrote address-computation code to better match windows 98
                allocation. VirtualAlloc may round down requested address *twice*.
                Replaced ASSERTs with (lower-level) Win32 MessageBox calls.
                (Thanks to Darryl Strickland (DStrickland@carolina.rr.com))
 *)

interface
uses
  Windows, SysUtils;

procedure SetGlobalVal(Index: Integer; Val: DWORD);

function GetGlobalVal(Index: Integer): DWORD;

function ThisFree: Boolean;

var
  InitFlag: array [0..63] of Integer = (
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  );
  
implementation

const SignatureBytes1 = $BABE01234567FEED;
      SignatureBytes2 = $F00D76543210B00B;
const iPagesBound     = 15;

type
    TMemMgrPack = record
         RefCount: Integer;  //Reference Count of the MemMgr
         Signature1: int64;
         MemMgr: TMemoryManager;
         Signature2: int64;
    end;
    PMemMgrPack = ^TMemMgrPack;


    procedure ValidatePack( p: PMemMgrPack );
    var pid: DWORD;
    begin
         // use pid for additional safety;
         p^.RefCount := 1;
         pid := GetCurrentProcessId;
         p^.Signature1 := SignatureBytes1 xor pid;
         p^.Signature2 := SignatureBytes2 xor pid;
    end;

    function IsPackValid( p: PMemMgrPack ): boolean;
    var pid: DWORD;
    begin
         pid := GetCurrentProcessId;
         Result := (p^.Signature1 = SignatureBytes1 xor pid) and
                   (p^.Signature2 = SignatureBytes2 xor pid);
    end;

var
  si: TSYSTEMINFO;
  OldMemMgr: TMemoryManager;
  requested, allocated: PMemMgrPack;

//  err: integer;
//  lpMsgBuf: PChar;
//  granul: integer;
  iPages: integer;

procedure SetGlobalVal(Index: Integer; Val: DWORD);
begin
  PCardinal(Integer(requested)+sizeof(TMemMgrPack)+Index*4)^ := val;
end;

function GetGlobalVal(Index: Integer): DWORD;
begin
  result := PCardinal(Integer(Requested)+sizeof(TMemMgrPack)+Index*4)^;
end;

function ThisFree: Boolean;
begin
  result := allocated = requested;
end;

initialization
  GetSystemInfo( si );
  iPages := 0;

  //next, fixed by Aimingoo
  repeat
    requested := si.lpMaximumApplicationAddress ;
    requested := pointer( (integer(requested) div $10000) * $10000 ); // align on start of last full 64k page
    dec(integer(requested), iPages * $10000);
    requested := pointer( (cardinal(requested) div si.dwPageSize) * si.dwPageSize ); // align on start of last full 64k page
    allocated := VirtualAlloc( requested, si.dwPageSize, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE );

    //find a free memory block or a valid MemMgr
    if (allocated <> nil) then
      if (requested = allocated) then
        Break
      else
    else
      if IsPackValid(requested) then
        Break;

    inc(iPages);
  until iPages > iPagesBound;

  if allocated <> nil then
  begin
    if requested <> allocated then
    begin
      MessageBox( 0, 'Shared Memory Allocator setup failed: Address was relocated.', 'FastShareMem', 0 );
      Halt;
    end;

    GetMemoryManager( allocated^.MemMgr );
    ValidatePack( allocated );
  end
  else
  begin
    if not IsPackValid( requested ) then
    begin
      MessageBox( 0, 'Shared Memory Allocator setup failed: Address already reserved.', 'FastShareMem', 0 );
      Halt;
    end;

    GetMemoryManager( OldMemMgr );
    SetMemoryManager( requested^.MemMgr );
    inc(requested^.RefCount);
  end;

finalization
  //next, fixed by Aimingoo

  (* fix Reference Count *)
  dec(requested^.RefCount);

  (* restore MemMgr to Old, only for DLL or other model *)
  if allocated = nil then
    SetMemoryManager( OldMemMgr )
  else
    if requested^.RefCount > 0 then
    begin
      //MessageBox( 0, 'Some Library none unload...', 'FastShareMem', 0 );
      TerminateProcess(GetCurrentProcess, 0);
    end;

  (* cleanup *)
  if requested^.RefCount = 0 then
    VirtualFree( allocated, 0, MEM_DECOMMIT or MEM_RELEASE )
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -