PDA

View Full Version : سوال: كمك در مورد از حافظه خارج كردن فايل هاي DLL در دلفي



moein.mojtaba
سه شنبه 10 اردیبهشت 1392, 14:44 عصر
با سلام خدمت دوستان گرامي
من يك برنامه طراحي كردم كه از يك Host Application و يك فايل DLL كه داراي فرم هست تشكيل شده .
وقتي در Host Application بر روي يك Button كليك مي كنم اين DLL اجرا مي شه .ولي وقتي فرم مربوط به DLL رو مي بندم ، فايل DLL از حافظه خارج نمي شه و فضاي زيادي رو اشغال مي كنه .تا وقتي كه Host Application رو نبستم با هر بار باز شدن فرم مربوط به DLL فضاي اشغال شده Ram چند برابر مي شه .مي خواستم در اين خصوص كمكم كنيد .ممنون ميشم .
البته مي دونم كه بايد بصورت Dynamic باشه ولي نتونستم كدش رو بنويسم.
كد هاي مربوط به Host Application :



procedure showmdichild(MainApp: TApplication; id, namefamily, skin,
CodeManager: string); stdcall; external 'PowerLib.dll' delayed;

procedure TForm1.sButton1Click(Sender: TObject);
begin
showmdichild(Application,Edit1.Text,Edit2.Text,Edi t3.Text,Edit4.Text);
end;


كد هاي مربوط به DLL :

var
DLLApp: TApplication;


//---------------------------------------

procedure showmdichild(MainApp: TApplication;id,namefamily,skin,CodeManager:string ); stdcall;
var
Child: TForm1;
begin
if not Assigned(DLLApp) then
begin
DLLApp := Application;
Application := MainApp;
end;
Child := TForm1.Create(Application.MainForm);
Child.Show;
end;


//--------------------------------
procedure MyDLLProg(Reason: integer);
begin
if Reason = DLL_PROCESS_DETACH then
if Assigned(DLLApp) then
begin
Application := DLLApp;
end;
end;
exports showmdichild;
//--------------------------------------

begin
DllProc := MyDLLProg;
end.





عكس هاي برنامه به همراه فضاي اشغال شده RAM:
اجراي بار اول
103505
اجراي بار دوم
103506

Felony
سه شنبه 10 اردیبهشت 1392, 15:05 عصر
در رویداد Close فرمی که در DLL پیاده کردید ، پارامتر Action رو با caFree مقدار دهی کنید .

moein.mojtaba
سه شنبه 10 اردیبهشت 1392, 17:31 عصر
ممنون از لطفتون
اين كار رو كردم ولي زماني كه مي خواد Load كنه حدود 60000k حافظه مي گيره و لي وقتي Dll رو مي بندم 15000k كم مي كنه . و كل DLL رو از حافظه پاك نمي كنه . كاري ديگه ميشه انجام داد .
ممنون

Mask
سه شنبه 10 اردیبهشت 1392, 20:37 عصر
نحوه Atach و DeAtach ، کردن dll تون اشتباهه.
در پستهای Mahan-1363 جستجو کنید. قبلا در رابطه با این موضوع روشهای لازم رو توضیح دادند.
در ضمن پستتون رو ویرایش کنید و کد ها رو در بلوک مربوطه قرار بدید.

moein.mojtaba
سه شنبه 10 اردیبهشت 1392, 21:46 عصر
ممنونم .اگه میشه بیشتر راهنمایی کنید .ممنون میشم

Felony
سه شنبه 10 اردیبهشت 1392, 23:33 عصر
کلا بهتره در این نوع کارها یک EntryPoint برای DLL نوشته بشه تا در زمان لود شدن DLL کلاس ها و ... مورد نظر initialize بشه و هنگام unload شدن حافظه اختصاصی به اشیاء و ... آزاد بشه ؛ در مورد نحوه نوشتن EntryPoint هم بارها قبلا توضیح دادم ، جستجو کنید .

در مورد اینکه میگید که حافظه کامل آزاد نمیشه ، مشکلی نیست ، Memory Manager ویندوز عملیات Cleanup رو همون موقع که شئ رو ازاد میکنید به صورت کامل انجام نمیده ، Memory Manager وقتی نیاز به حافظه داشته باشه و حافظه خالی برای استفاده وجود نداشته باشه ، عملیات Cleanup رو انجام میده و حافظه رو بازسازی میکنه .

moein.mojtaba
چهارشنبه 11 اردیبهشت 1392, 07:52 صبح
باز هم ممنون .جستجو كردم .يه چيز هايي رو هم پيدا كردم.
اگه ميشه لطف كنيد و همين Entry Point را داخل كد بالا برام بزاريد .

moein.mojtaba
چهارشنبه 11 اردیبهشت 1392, 12:50 عصر
من اين كد رو داخل Host Application‌اينجوري تغيير دادم . لي وقتي روي دكمه اجراي DLL كليك مي كنم كلا برنامه بسته مي شه.لطفا كمكم كنيد تا اين رو بتونم درستش كنم

type
showmdichild = Procedure(MainApp: TApplication; id, namefamily, skin,
CodeManager: string);


procedure TForm1.sButton1Click(Sender: TObject);
var
libhandel: THandle;
tsadta: showmdichild;
begin
libhandel := LoadLibrary('PowerLib.dll');
try
if libhandel <= 32 then
raise Exception.Create('فايل DLL مورد نظر وجود ندارد');
@tsadta := GetProcAddress(libhandel, 'showmdichild');
if not(@tsadta = nil) then
begin
tsadta(Application, Edit1.Text, Edit2.Text, Edit3.Text, Edit4.Text);
end
else
begin
RaiseLastOSError;
end;
finally
FreeLibrary(libhandel);

end;

بقيه كد ها داخل DLL همون قبلي هست .

moein.mojtaba
شنبه 14 اردیبهشت 1392, 09:31 صبح
كسي نمي تونه جواب بده ؟