PDA

View Full Version : مشکل در آزاد کردن Data Module داخل DLL



Felony
سه شنبه 24 فروردین 1389, 07:24 صبح
:لبخندساده:سلام ،

در حال نوشتن یک DLL هستم ، به جای اینکه کامپوننت های Non Visual رو به صورت RunTime بسازم تصمیم گرفتم کامپوننت ها رو روی یک Data Module قرار بدم و چون اولین بارم بود که این کار رو میکردم تجربه ای نداشتم ، وقتی تو یونیت پلاگین متدها اشیاء روی Data Module رو صدا میزدم پیغام خطا میگرفتم و فهمیدم باید Data Module رو هم مثل فرم Create کرد ، با کد زیر Data Module رو تو DLL میسازم :


DM_Main:= TDM_Main.Create(nil);

حالا برنامه ای که از DLL استفاده میکنه زمان بسته شدن پیغام خطا میده چون Data Module آزاد نشده !

من برای آزاد کردن فرم ها این کار رو میکردم :

1.کد زیر رو تو یونیت فرم قرار میدادم :

// Free components on close //////////////////////////
procedure TFRM_Properties.DestroyPlugin(var Msg: TMessage);
var
i: Integer;
begin
for i := ComponentCount - 1 downto 0 do
begin
if (Components[i] is TControl) then
TControl(Components[i]).Parent := nil;
Components[i].Free;
end;
release;
inherited;
end;
//////////////////////////////////////////////////////

و تو رویداد OnClose با کد زیر فرم رو آزاد میکردم :

SendMessage(FRM_Properties.Handle, WM_DESTROY, 0, 0);

ولی Data Module هندل نداره ...

باید چی کار کنم ؟

vcldeveloper
سه شنبه 24 فروردین 1389, 18:19 عصر
فهمیدم باید Data Module رو هم مثل فرم Create کرد
Data Moduleها خودشان نوعی فرم هستند. همه اشیاء را باید قبل از استفاده Create کرد.


و تو رویداد OnClose با کد زیر فرم رو آزاد میکردم :
1.SendMessage(FRM_Properties.Handle, WM_DESTROY, 0, 0);



با این کارتون اشتباه می کردید، چون این کد، فرم را آزاد نمیکنه، بلکه فقط پنجره اختصاص داده شده به آن را آزاد میکنه. برای آزاد کردن یک شی باید متد Free آن فراخوانی بشه. در اون مورد خاص، شما باید در رویداد OnClose آن فرم از Action := caFree استفاده می کردید.


باید چی کار کنم ؟
باید برای DLL خودتون Entry Point بنویسید:


procedure EntryPoint(Event: DWord);
begin
case Event of
DLL_PROCESS_ATTACH : {Create an instance of your datamodule here};
DLL_PROCESS_DETACH : {Free your datamodule instance here};
end;
end;

begin
Dllproc := @EntryPoint;
EntryPoint(DLL_PROCESS_ATTACH);
end.

کد بالا را در داخل فایل DPR مربوط به DLL خودتون بنویسید، و در محل های مشخص شده هم کد مربوط به ساختن و آزاد کردن DataModule خودتون رو بنویسید.

Felony
سه شنبه 24 فروردین 1389, 19:05 عصر
ممنون علی آقا اون کدی که در مورد EntryPoint گزاشتید کارم رو راه انداخت ، فقط از یک خطش سر در نیاوردم ، میشه بگید چرا اشاره گر EntryPoint رو به Dllproc اختصاص دادید ؟

vcldeveloper
سه شنبه 24 فروردین 1389, 19:25 عصر
میشه بگید چرا اشاره گر EntryPoint رو به Dllproc اختصاص دادید ؟
برای اینکه اون Procedure به تنهایی چیزی نیست، بلکه با نوشتن اون Procedure و اختصاص دادنش به متغیر عمومی Dllproc، دارید به دلفی میگید که به جای dllproc پیش فرض، می خواید از این تابع استفاده کنید.
dllproc کدی هست که در زمان های خاصی (مثل لود شدن DLL در فضای آدرس یک Process) اجرا میشه.