مشاهده نسخه کامل
: استفاده از تابع GetSystemInfo در VB.Net و فرق آن در VB6.0
vb.civil
05-04-2018, 11:29
با سلام
دوستان من با این کد در VB6.0 میتونم کار کنم و مقادیر lpMinimumApplicationAddress و lpMaximumApplicationAddress رو میگیرم
ولی همین کد در VB.Net کار نمیکنه
متن خطا در vb.net
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt
کد در vb.net
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
همین کد در VB6.0 کار کار میکنه
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
سلام
شما در حال فراخوانی یک API ویندوز هستید، همه جایگذاری ها بر اساس مختصات و آدرس خانه های حافظه انجام میشود.
یک بایت کم و زیاد شود، (حتی خطا هم در برخی موارد نمیدهد) ولی کل ساختار از آن نقطه به بعد را خراب میکند.
در این خصوص ، دو تفاوت در VB6 و نسل های بعدی VB وجود دارد که اگر در حال تبدیل کد هستید باید به آنها دقت کنید.
اولین تفاوت در ابعاد اعداد صحیح Integer, Long است که در نسخه های جدید دو برابر شده.
یعنی VB6-Integer=VB7-Short و VB6-Long=VB7-Integer !
درواقع Long دات نت 8 بایتی است که در VB6 همچین چیزی وجود ندارد.
دومین تفاوت آن است که VB6 همواره x86 کامپایل و اجرا میشده. (32 بیتی)
ولی نسخه های جدید توانایی کامپایل و اجرای x64 را هم دارند. (64 بیتی)
شما میتوانید در منوی Build>Configuration کاری کنید که پروژه شما فقط 32 بیتی کامپایل شود و البته exe تان بدون مشکل در سیستم عامل های 64 بیتی هم کار خواهد کرد.
ولی راه بهتر آن است که اجازه دهید برنامه تان AnyCpu کامپایل شود و خودکار بتواند 32 بیتی یا 64 بیتی اجرا شود.
این حالت بهتر است ولی در فراخوانی API های ویندوز نیاز به دقت بیشتری دارد.
مشکل آنجاست که در اجرای 32 بیتی هر اشاره گر 32 بیت است، یعنی Integer جدید.
ولی در اجرای 64 بیتی هر اشاره گر 64 بیت است، یعنی Long نیاز است.
مثلا در کد خودتان ، lpMinimumApplicationAddress اشاره گر حافظه است.
پس برای اجرای 32 بیتی باید lpMinimumApplicationAddress As Integer باشد.
و برای اجرای 64 بیتی باید lpMinimumApplicationAddress As Long باشد.
برای حل این مشکل دوگانه ، دات نت نوع IntPtr را دارد که مختص اشاره گرها است.
خلاصه آنکه ، باید با توجه به مستندات MSDN نوع متغییر مناسب را انتخاب کنید...
صفحه زیر را مرور کنید:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
تبدیل مستندات صفحه فوق الذکر به VB.Net چنین خواهد بود:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
البته شاید بهتر باشد، بجای Integer و Short کد بالا از UInteger و UShort استفاده کنید، ولی مشکلی ندارد و گفتم زیاد پیچیده نشود...
این کد حداقل مورد نیاز است تا در اجرای 32 بیتی و 64 بیتی برنامه تان به خوبی و درستی عمل کند.
موفق باشید.
vb.civil
06-04-2018, 11:03
_H2_ ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]) عزیز مرسی بابت توضیحات کامل
اما من باز هم نتونستم مقادیر مناسبی رو خروجی بگیریم
خروجی vb.net
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
خروجی vb6
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
در ضمن حافظه رم من دو تا 8 گیگ هست که تو هیچکدوم نشون داده نشده !
سلام
حتما میدانید که عدد منفی دات نت درواقع مثبت است و اشاره به انتهای حافظه دارد... (میتوانید بجای IntPtr از UIntPtr استفاده کنید)
دات نت شروع آدرس دهی را 0x1.0000 و پایان را 0xFFFF.FFFF.FFFE.FFFF گزارش داده که دور از ذهن نیست.
VB6 هم چون 32 بیتی اجرا شده ، کل محدوده 31 بیتی یعنی 0x1.0000 تا 0x7FFE.FFFF را گزارش داده.
یعنی در کل 0x10000 از دو طرف رزو شده...
و...
و...
و...
بگذریم!
شما میخواهید با GetSystemInfo مقدار RAM رایانه تان را بدست آورید؟؟! :n02:
این اعداد ارتباطی با RAM واقعی شما ندارد.
در VB.Net میتوانید از Microsoft.VisualBasic.Devices.ComputerInfo و خصیصه TotalPhysicalMemory استفاده کنید، با چند مگ اختلاف (رزو سیستم عامل) مقدار RAM تان را گزارش میدهد.
چندین روش بهتر هم وجود دارد، گمانم یکی از ساده ترین کدها ، این باشد
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
فقط دقت کنید API فوق در Windows Vista SP1 به بعد وجود دارد، یعنی در XP کار نمیکند.
موفق باشید.
vBulletin , Copyright ©2000-2025, Jelsoft Enterprises Ltd.