PDA

View Full Version : گفتگو در رابطه با Borland Memory Manager



مهران موسوی
جمعه 25 بهمن 1387, 23:27 عصر
سلام دوستان .

میخواستم با چند نفر از دوستان متخصص در زمینه ی برنامه نویسی سیستمی و اشنا با مسائل مدیریت حافظه و .. گفتگو داشته باشم .

میخواستم بدونم Borland Memory Maneger تا چه حد میتونه در مدیریت حافظه ی DLL های ما نقش مفیدی رو ایفا کنه ... !!؟؟

مثلا وقتی ما یک DLL مینویسیم که قراره توسط برنامه های سیستمی مثلا Explorer.exe یا برنامه های کاربردی دیگه استفاده بشه اگه در DLL خودمون از یونیت ShareMem استفاده کنیم که خودش باعث میشه برنامه ای که از DLL ما استفاده کرده به Borlandmm.dll نیازمند بشه . خوب حالا میخوام بدونم استفاده از این حالت باعث ایجاد اختلال در پروسسی که از DLL ما استفاده کرده نمیشه ؟؟ :متفکر:

vcldeveloper
جمعه 25 بهمن 1387, 23:42 عصر
اصولا BorlandMM یک موجود آشغالی هست! استفاده از آن به میزان زیادی کارایی برنامه را کاهش میده. اگر از دلفی 2007 یا نسخه های بالاتر استفاده می کنید، بجای ShareMem از SimpleShareMem استفاده کنید که مستقیما از FastMM برای مدیریت حافظه DLL استفاده میکنه. هم مشکل مورد نظر (در مورد نوع های داده ایی مثل string) را برطرف میکنه، هم کارایی بسیار بالاتری داره.


مثلا وقتی ما یک DLL مینویسیم که قراره توسط برنامه های سیستمی مثلا Explorer.exe یا برنامه های کاربردی دیگه استفاده بشه
اون وقت دیگه از نوع داده های اختصاصی دلفی مثل string یا dynamic array نباید استفاده کنید، و نیازی هم به ShareMem ندارید. علتش هم ساده هست، این نوع های داده مخصوص دلفی هستند، و برنامه هایی که با سایر زبان ها نوشته شدند اطلاعی از آنها ندارند. بهترین روش برای انتقال متن به برنامه هایی که با سایر زبان ها نوشته شدند در ویندوز استفاده از PChar هست. این همون کاری هست که ویندوز برای انتقال متن توسط APIهای خودش استفاده میکنه.

مهران موسوی
جمعه 25 بهمن 1387, 23:49 عصر
علی جان ممنون از جوابت . یک نکتهی ابهام برام مونده ... یعنی اگه من از Pchar در dll خودم استفاده کنم هیچ مشکلی برام پیش نمیاره ؟؟ چون اگه از String بدون ShreMem استفاده کنم بعد از صدا زده شدن تابع من در DLL به تعدا مثلا 4 بار برنامه ای ای که اون رو صدا زده Dont Send یا اررور های مربوط به سرریز حافظه میده .. یعنی اگه از Pchar و PWideChar استفاده کنم مشکلم حل میشه ؟

راستی خودم باید حافظه ی مربوط به Pchar رو بگیرم و ازاد کنم ؟ اگه اینجوری باشه که خیلی درد سر داره !!! :گیج: یا اینکه نیازی به گرفتن و ازاد ساختن دستی حافظه نیست ؟؟ اگه هست یعنی به صورت زیر ؟؟

مثلا :


var
a:pchar;
begin

a:=StrAlloc(100);

StrCopy(a,'Test Pchar');


MessageBox(0,a,'Use Pchar',0);

StrDispose(a);خب حالا برای pwideChar چیکار کنم ؟ ایا تابع ای برای Pwidechar هست که مثل StrAlloc در Pchar عمل کنه ؟

مهران موسوی
شنبه 26 بهمن 1387, 00:46 صبح
راستی برای نوع های داده ای که خودمون تعریف میکنیم باید چه جوری رفتار کنیم توی Dll ها ؟ مثلا :


type
MyType = ( MTOne,MTTwo,MTTree);

حالا در هنگام استفاده چه جوری باید عمل کنیم ( البته در DLL ها ) !!؟؟

vcldeveloper
شنبه 26 بهمن 1387, 04:32 صبح
یعنی اگه من از Pchar در dll خودم استفاده کنم هیچ مشکلی برام پیش نمیاره ؟
خیر نمیاد. مشکل string در dll این هست که در برنامه های غیر دلفی قابل شناسایی نیست، چون یک نوع داده مخصوص دلفی هست. در برنامه های دلفی هم که از اون dll استفاده می کنند، با توجه به اینکه DLL و فایل EXE از Heap جداگانه ایی استفاده می کنند، و string در heap نگهداری میشه، مشکلاتی پیش میاد. کاری که SimpleShareMem میکنه اینه که بجای انتقال تمام ترافیک مربوط به مدیر حافظه به BorlandMM، میاد FastMM را طوری تنظیم میکنه که برای DLL و EXE از یک Heap مشترک استفاده بشه.
اما باز هم مشکل هماهنگی با سایر زبان ها باقی میمانه. البته این مشکل فقط برای دلفی نیست، هر زبانی در انتقال داده های مخصوص به خودش به سایر زبان ها مشکل داره.



راستی خودم باید حافظه ی مربوط به Pchar رو بگیرم و ازاد کنم ؟ اگه اینجوری باشه که خیلی درد سر داره !!! :گیج: یا اینکه نیازی به گرفتن و ازاد ساختن دستی حافظه نیست ؟؟
PChar فقط یک pointer هست. باید براش حافظه در نظر گرفته بشه. اینکه چطور براش حافظه در نظر بگیرید، بستگی به نوع استفاده از DLL شما داره. می تونید از نحوه کار ویندوز الگوبرداری کنید؛ توابع API ویندوز از کد فراخوان تابع میخوان که حافظه مورد نیاز را اختصاص بده، و فقط یک اشاره گر از نوع PChar به تابع برگردانه. در این صورت، مسئولیت تخصیص حافظه با کد فراخوان تابع هست، نه با خودِ تابع. به عنوان نمونه میشه تابع GetWindowText اشاره کرد.


خب حالا برای pwideChar چیکار کنم ؟ ایا تابع ای برای Pwidechar هست که مثل StrAlloc در Pchar عمل کنه ؟
قبلا هم توضیح دادم که نوع های داده ایی مثل PChar, Char, یا string متناسب با نسخه دلفی، به نوع های دیگه ایی اشاره می کنند؛ در واقع این نوع ها نوع های عمومی هستند. مثلا در نسخه های دلفی قبل از 2009، PChar به PAnsiChar اشاره میکنه، ولی در دلفی 2009 این نوع داده به PWideChar اشاره میکنه. Char و string هم همینطور. مزیت استفاده از نوع های عمومی این هست که شما در هر نسخه ایی از دلفی که از آنها استفاده کنید، درست جواب میدند، یعنی شما اگر در کدتان از PChar استفاده کنید، اگر کد در دلفی 2007 کامپایل شود، می شود PAnsiChar، و درست کار می کند، اگر هم در دلفی 2009 کامپایل شود، می شود PWideChar و درست کامپایل می شود. ولی اگر مستقیما از PAnsiChar استفاده کنید، در دلفی 2009 کد کامپایل نمی شود، چون دلفی 2009 از نسخه های یونیکد توابع ویندوز استفاده می کند. اگر هم از PWideChar استفاده کنید، در نسخه های قبل از دلفی 2009 کامپایل نمی شود، چون آن نسخه ها از توابع ANSI ویندوز استفاده می کنند.


راستی برای نوع های داده ای که خودمون تعریف میکنیم باید چه جوری رفتار کنیم توی Dll ها ؟
بحث نوع داده در DLL فقط زمانی مهم هست که قرار باشه اون نوع داده در برنامه فراخوان DLL هم استفاده بشه، مثلا به عنوان یکی از پارامترهای یکی از توابع، یا خروجی یکی از توابع. در غیر اینصورت، نیاز نیست نگران آن باشید؛ یعنی اگر شما در داخل تابع خودتان string یا هر نوع داده دیگه ایی را استفاده کنید، مهم نیست، ولی نباید از آن در پارامترها یا خروجی تابع استفاده کنید.

نوع های داده ایی مثل enum ها را می توانید در یک یونیت جداگانه تعریف کنید که بین DLL و EXE شما مشترک باشد. سایر زبان ها باید آن را به نوع داده ایی که در آن زبان ها پشتیبانی می شود تبدیل کنند. مثلا اگر زبانی از enum پشتیبانی نمی کند، می تواند به هر یک از مقادیر MTOne,MTTwo,MTTree l مقدار عددی صفر تا دو بدهد. این یونیت شما حکم فایل header در زبان های C یا C++ را دارد. همانطور که برای استفاده از یک DLL نوشته شده با C باید فایل Header آن را به دلفی ترجمه کنید، یونیت مورد نظر شما هم باید توسط برنامه نویس C به یک فایل Header آن زبان ترجمه شود.

مهران موسوی
شنبه 26 بهمن 1387, 06:00 صبح
بحث نوع داده در DLL فقط زمانی مهم هست که قرار باشه اون نوع داده در برنامه فراخوان DLL هم استفاده بشه، مثلا به عنوان یکی از پارامترهای یکی از توابع، یا خروجی یکی از توابع. در غیر اینصورت، نیاز نیست نگران آن باشید؛ یعنی اگر شما در داخل تابع خودتان string یا هر نوع داده دیگه ایی را استفاده کنید، مهم نیست، ولی نباید از آن در پارامترها یا خروجی تابع استفاده کنید.

یعنی فقط محدودیت زمانی هست که بخواییم نوع داده های اختصاصی در برنامه ی مقصد استفاده بشه ؟ یعنی اگه فقط از اون نوع ها در بدنه ی توابع خودمون استفاده کنیم هیچ مشکلی پیش نمیاد .. مثلا اگه بخواییم از string استفاده کنیم بعد از پایان یافتن تابع حافظه ی استفاده شده توسط اون String خود به خود ازاد میشه یا باید ما خودمون ازادش کنیم ؟؟

vcldeveloper
شنبه 26 بهمن 1387, 16:12 عصر
یعنی اگه فقط از اون نوع ها در بدنه ی توابع خودمون استفاده کنیم هیچ مشکلی پیش نمیاد
خیر.

مثلا اگه بخواییم از string استفاده کنیم بعد از پایان یافتن تابع حافظه ی استفاده شده توسط اون String خود به خود ازاد میشه یا باید ما خودمون ازادش کنیم ؟؟
خودش آزاد میشه