type TDay = (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday) var Name : String; {256 Bytes} X, Y : Integer; {4 + 4 = 8 Bytes} List : array [0..10] of Double; {8 * 11 = 88 Bytes} Today : TDay; {1 Byte}
var ;Number : ^Integer ;Name : ^String
var ;Something : Pointer
begin
New(Something);
Dispose(Something);
end;
برای تخصیص حافظه کامپایلر باید بداند که نوع داده ما برای تخصیص حافظه چیست:
type
IntPtr = ^Integer;
var
Something : Pointer;
begin
Something := New(IntPtr);
Integer(Something^) := 10;
Dispose(Something);
end;
تخصیص بلاکی از حافظه
ما میتوانیم از اشاره به بلاکهایی از تخصیص حافظه در سیستم استفاده کنیم. این کار را با رویههای GetMem و FreeMem برای تخصیص و آزاد سازی حافظه استفاده میکنیم.
var
Something : Pointer
begin
GetMem(Something, 100);
FreeMem(Something, 100);
end;
اشاره به حافظه از قبل تخصیص داده شده
هر دو نوع اشارهگرها می توانند به هر جایی از حافظه اشاره بکنند. این بدان معناست که آنها میتوانند اشاره به فضای اشغال شده با دادههایی که در حال حاضر موجودند داشته باشند. این نمونه اشارهگر احتیاجی به تخصیص حافظه ندارد.
var
Something : Pointer;
MyString : PChar; // type PChar = ^Char;
begin
GetMem(Something, 100);
MyString := Something;
StrCopy(Something, 'Hello World');
FreeMem(Something, 100);
end;
حافظه Heap
Heap شامل قسمتی از حافظه موجود در یک برنامه است که آنرا حافظه پویا می نامیم. Heap بخشی است که در آن تخصیص و تعریف حافظه به صورت تصادفی (Random) اتفاق میافتد. این به آن معناست که اگر شما سه بلاک از حافظه را به طور متوالی تخصیص دهید، می توانید بعد از هر دستور آنرا از بین ببرید. مدیر Heap جزئیات را برای شما نگهداری می کند. بنابراین شما به سادگی می توانید یک حافظه جدید را با GetMem و یا بوسیله صدا زدن constructor هنگام ساختن یک شی درخواست کنید و دلفی به شما یک بلاک جدید را برخواهد گرداند. Heap یکی از سه فضای موجود در برنامه کاربردی را استفاده کرده و دوتای دیگر به صورت فضای یکپارچه (Global) و پشته قرار می گیرند.
حافظه Stack
Stack شامل قسمتی از یک بخش از حافظه موجود یک برنامه است که دینامیکی است اما برای تخصیص و آزادسازی فرامین مخصوص دارد. تخصیص Stack به صورت LIFO می باشد. این بدان معناست که آخرین حافظه شیء شما تخصیص داه خواهد شد و سپس حذف می شود. حافظه پشته در روتینهای نوعی استفاده میشود. وقتی شما یک روتین را صدا میزنید، پارامترهایش و روتین نوع آن در پشته ریخته می شود. همچنین پارامترهایی که در یک روتین تعریف میشوند، در پشته ذخیره میشوند و وقتی روتین خاتمه پیدا می کند تمام آنها به طور خودکار از بین می رود.
ایجاد یک DLL
با استفاده از منو فایل گزینه New Items را انتخاب کنید و آیتم DLL Wizard را انتخاب نمایید. حال به فایل ایجاد شده، یک فرم با استفاده از روش بالا اضافه نمایید. دقت نمایید که Application را بجای فرم انتخاب ننمایید. حال اگر فرض کنیم که نام فرم شما Demo باشد و بانام UDemo.pas آنرا ذخیره کرده باشید. باید در فایل DLL بصورت زیر کد نویسی نمایید:
library demodll;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
SysUtils,
Classes,
UDemo in 'UDemo.pas' {Demo};
{$R *.res}
procedure ShowdemoForm;stdcall;
begin
Demo :=Tdemo.Create(nil);
demo.Show;
end;
function ShowdemoFormModal:integer;stdcall;
begin
demo :=Tdemo.Create(nil);
Result := demo.ShowModal;
end;
Exports
ShowDemoForm,
ShowdemoFormModal;
begin
end.
دقت کنید که نام DLL فوق DemoDll می باشد و با نام DemoDll.dpr ذخیره گردیده است.
حال بر روی فرم موجود تمام دکمهها و آبجکتهای مورد نظرتان را اضافه و کد نویسی کنید (اختیاری). در پایان در منو Project گذینه Build DemoDll را انتخاب کرده و اجرا نمایید. فایلی با نام DemoDll.dll ایجاد می گردد که برای استفاده آماده است.
استفاده از یک DLL بصورت دینامیکی
برای استفاده از یک DLL بصورت دینامیکی، ابتدا نام توابعی را که در فایل DLL شما موجود است بصورت زیر تعریف نمایید:
unit UMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TShowdemoFormModal= Function :integer;
.
.
.
دقت کنید که نام برنامه انتخابی پیش فرض Main و با نام UMain.pas ذخیره گشته است. حال برای لود کردن DLL یادشده، یک دکمه بر روی فرم قرارداده آنرا بصورت زیر کد نویسی کنید:
var
hndDLLHandle:THandle;
ShowdemoFormModal:TShowdemoFormModal;
procedure TFMain.Button1Click(Sender: TObject);
begin
try
hndDLLHandle:=LoadLibrary('Demodll.dll');
if hndDLLHandle <> 0 then begin
@ShowdemoFormModal:=getProcAddress(hndDLLHandle,'ShowdemoFormModal');
if addr(ShowdemoFormModal) <> nil then begin
ShowdemoFormModal;
end
else
showmessage ('function not exists ...');
end
else
showMessage('Dll Not Found!');
finally
freelibrary(hndDLLHandle);
end;
end;
فرم شما آماده اجراست. در پایان متذکر می شوم که استفاده ار روش دینامیکی در لود کردن DLL ها باعث پایین آمدن سرعت نمایش فرمها و در عوض بالارفتن سرعت برنامه خواهد شد.
StatusBar می باشد. انجام این کار بسیار ساده است. برای این کار کافی است بر روی فرم خود یک StatusBar اضافه نمایید حالا در قسمت تعاریف متغیر های عمومی کد زیر را بنویسید:
ProgressBar1: TprogressBar;
در ادامه دستورات زیر را در خاصیت OnCreate فرم خود بنویسید:
var
ProgressBarStyle: LongInt;
begin
{create a run progress bar in the status bar}
ProgressBar1 := TProgressBar.Create(StatusBar1);
ProgressBar1.Parent := StatusBar1;
{remove progress bar border}
ProgressBarStyle := GetWindowLong(ProgressBar1.Handle, GWL_EXSTYLE);
ProgressBarStyle := ProgressBarStyle - WS_EX_STATICEDGE;
SetWindowLong(ProgressBar1.Handle, GWL_EXSTYLE, ProgressBarStyle);
{set progress bar position and size - put in Panel[2]}
ProgressBar1.Left := StatusBar1.Panels.Items[0].Width +
StatusBar1.Panels.Items[1].Width + 4;
ProgressBar1.Top := 4;
ProgressBar1.Height := StatusBar1.Height - 6;
ProgressBar1.Width := StatusBar1.Panels.Items[2].Width - 6;
{set range and initial state}
ProgressBar1.Min := 0;
ProgressBar1.Max := 100;
ProgressBar1.Step := 1;
ProgressBar1.Position := 0;
end;
حالا برای آنکه پس از خارج شدن از فرم حافظه اشغال شده آزاد گردد، در قسمت OnDestroy در Event فرمتان دستور زیر را اضافه نمایید:
ProgressBar1.free;