کامپایل یک برنامه C#

کامپایل یک برنامه C#

اجرای برنامه‌های C# از طریق کامپایلر C# دو نوع اطلاعات مهم ایجاد می‌کند : کد و metadata. در مطلب زیر درباره این دو نوع اطلاعات بحث خواهیم نمود.

 زبان سطح میانی مایکروسافت MSIL

کدی که توسط کامپایلر C# تولید می‌شود به زبان خاصی است که به آن، زبان سطح میانی مایکروسافت یا MSIL می‌گویند. این زبان مجموعه‌ای از دستورالعمل‌ها است که نحوه اجرای برنامه شما را معین می‌کند. این کد حاوی دستورالعمل‌هایی جهت مقداردهی متغیرها، فراخوانی اشیاء، متدها و کنترل خطا می‌باشد. باید به این نکته نیز اشاره کرد که زبان C# تنها زبانی نیست که کد آن به MSIL تبدیل می‌شود، بلکه کد تمامی زبانهای تحت .Net به زبان MSIL تبدیل می‌شوند، یعنی به محض کامپایل، کدهای نوشته شده توسط شما به کد زبان MSIL تبدیل می‌شود. به دلیل اینکه کد تمامی زبانهای تحت .Net به دستورالعملهای مشابهی در MSIL تبدیل می‌شوند و به دلیل اینکه تمامی این زبانها دارای محیط اجرایی یکسانی هستند، از اینرو این زبانها به راحتی می‌توانند با یکدیگر ارتباط برقرار نماییند و از کدهای یکدیگر استفاده کنند و بدون مشکل با یکدیگر کار کنند.

 یکی از مزایای مهم MSIL اینست که دستورالعملهای آن مخصوص پردازنده‌ای (CPU) خاص طراحی نشده است. به بیان دیگر MSIL هیچ چیز در مورد CPU ماشینی که بر روی آن اجرا می‌شود نمی‌داند و CPU ماشین نیز چیزی در مورد MSIL نمی‌داند. حال سوالی که در اینجا مطرح می‌شود آنست که پس CPU چگونه کدهای MSIL را اجرا می‌کند؟ باید گفت که کدهای MSIL بر روی هر ماشینی، به دستورالعملهای خاص آن ماشین تبدیل می‌گردند. این عمل، که تنها در اولین اجرای برنامه بر روی ماشینی خاص اتفاق می‌افتد را با نام "کامپایل آنی" یا JIT  می‌گوئیم. وظیفه کامپایلر JIT نیز تبدیل کدهای MSIL به دستورالعمل‌های خاص ماشینی است که برنامه بر روی آن اجرا می شود.

همانطور که ملاحظه می‌کنید این مرحله بسیار جالب است. اما شاید این سوال در ذهن شما مطرح شود که، زمانیکه کامپایلر می‌تواند کدی منطبق با دستورالعمل‌های پردازنده‌ای که روی آن اجرا می‌شود تولید نماید، پس چه لزومی به تبدیل این کدها به زبان MSIL وجود دارد؟ این عمل دقیقا عملی است که در گذشته و توسط کامپایلرهای قدیمی انجام می شد، اما دلایلی برای تبدیل کدها به زبان MSIL وجود دارد. اولین و مهمترین دلیل آنست که کدهای کامپایل شده به زبان MSIL را می‌توان به سادگی به سخت‌افزار دیگری نیز منتقل نمود. برای مثال تصور کنید برنامه‌ای را بر روی کامپیوتر شخصی خود به زبان C# نوشته و می‌خواهید آنرا به کامپیوتر جیبی خود منتقل نمایید. همانطور که می‌دانید این دو نوع کامپیوتر دارای پردازنده‌هایی متفاوت هستند و دستورالعمل‌های هر یک از این پردازنده‌ها نیز با یکدیگر متفاوت است. از اینرو برنامه شما فقط بر روی کامپیوتر شخصی قابل اجرا خواهد بود و نمی‌توانید آنرا بر روی سخت افزار دیگری منتقل کنید. در این شرایط شما به دو کامپایلر نیاز خواهید داشت : یک کامپایلر که برنامه C# شما را برای CPU کامپیوتر شخصی کامپایل کند و کامپایلر دیگری که این برنامه را برای کامپیوتر جیبی کامپایل نماید. همچنین در این حالت باید برنامه خود را دوبار کامپایل نمایید. اما با استفاده از MSIL تنها یکبار برنامه خود را کامپایل می‌کنید. در این حالت با نصب .Net Framework و JIT بر روی کامپیوتر شخصی خود، برنامه‌تان اجرا می‌شود و با نصب آن بر روی کامپیوتر شخصی، برنامه شما اجرا می‌شود. حال شما کد MSIL ای دارید که بر روی هر ماشینی که دارای کامپایلر JIT مربوط به .Net Framework است، اجرا می شود.

 یکی دیگر از مزایای استفاده از زبان MSIL در آنست که کدهای تولید شده در این مرحله به سادگی در پروسه تایید کد (Code Verification) قابل خواندن هستند. پروسه تایید کد، پروسه‌ای است که در آن JIT کد تولید شده را بررسی می‌کند تا فاقد هرگونه خطا و مشکل باشد. از جمله بررسی‌هایی که در این مرحله انجام می‌شود عبارتند از : بررسی دسترسی صحیح به حافظه، استفاده از متغیر صحیح، تبدیل صحیح انواع مختلف به یکدیگر و .... این بررسی ها باعث می‌شوند  تا برنامه‌ها بهنگام اجرا دچار مشکل نشده و با موفقیت اجرا شوند. تولید کدهای مختص به یک نوع پردازنده، هرچند سرعت اجرا را با بالا می‌برد اما کدی تولید می‌کند که بررسی آن بسیار دشوار است. تبدیل کدهای نوشته شده به زبان C# به  کدی مختص پردازنده‌ای خاص باعث ایجاد کدی می‌گردد که در مرحله تایید کد غیر قابل تشخیص است و یا به سختی قابل بررسی است.

 Metadata

پروسه کامپایل، علاوه بر کد اصلی برنامه، حاوی خروجی دیگری با عنوان Metadata می باشد که بخش بسیار مهمی در به اشتراک‌گذاری کدهای .Net می‌باشد. چه بخواهید تا برنامه‌ای مستقل با C# تولید کنید و چه بخواهید کلاسی تولید کنید که در برنامه‌ای دیگر مورد استفاده قرار گیرد، ممکن است بخواهید تا از کدهایی که قبلاً کامپایل شده‌اند استفاده نمایید. این کد یا توسط مایکروسافت بعنوان بخشی از .Net Framework پشتیبانی می‌شوند و یا توسط شخصی دیگر منطبق با .Net تولید شده‌اند. زمانیکه بخواهید از این کد استفاده کنید، کامپایلر C# شما باید اطلاعاتی درباره متغیرها و نوع متغیرهای بکار رفته در این کد در اختیار داشته باشد تا بتواند خود را با آن منطبق نماید.

 Metadata را می‌توان بعنوان فهرست اطلاعات موجود در کدی که قبلاً کامپایل شده در نظر گرفت. C# فایل Metadata را در هنگام تولید کد MSIL تولید می‌کند و در آن اطلاعات مفیدی را قرار می‌دهد. این فایل حاوی اطلاعاتی در مورد کلیه کلاسهای کد تولید شده و ساختار آنها می‌باشد. همچنین در Metadata تمامی متدها و متغیرهای بکار رفته در کلاس بطور کامل توصیف شده و برای برنامه‌های دیگر قابل خواندن است. بعنوان مثال یک برنامه می‌تواند با استفاده از Metadata موجود، لیست کلیه متدهای موجود را استخراج کرده و مورد استفاده قرار گیرد. تمامی اطلاعات لازم جهت توصیف و بررسی یک کلاس در Metadata قرار می‌گیرد.

 اسمبلی‌ها (Assemblies)

در اکثر موارد، شما از زبان C# بعنوان زبانی برای تولید برنامه‌های کاربردی استفاده می‌کنید. این برنامه‌های کاربردی بصورت فایلهایی اجرایی در می‌آیند که دارای پسوند .EXE هستند. ویندوز همواره فایلهای اجرایی را با پسوند .EXE می‌شناسد و C# نیز تولید اینگونه فایلها را کاملاً پشتیبانی می‌کند.

 اما زمانهایی هستند که نیازی به تولید کل یک برنامه نیست و تنها لازم است تا کلاس و یا ابزاری برای یک برنامه جامع‌تر تولید شود. برای مثال فرض کنید می‌خواهید ابزاری با زبان C# تولید کنید و آنرا به گروهی بدهید که با VB.Net کار می‌کنند. در چنین شرایطی بجای تولید فایل اجرایی .EXE، فایل اسمبلی تولید می‌شود.

 اسمبلی بسته‌ای حاوی کد و Metadata است. هنگامیکه مجموعه‌ای از کلاسها را در یک اسمبلی جمع می‌کنید، تمامی این کلاسها بعنوان یک واحد در نظر گرفته می‌شوند و دارای سطوح یکسانی هستند. می‌توان به اسمبلی بعنوان یک DLL منطقی (Logical DLL) نگریست. در .Net بحث اسمبلی بسیار شبیه به Microsoft Transaction Server و COM+ است.

 بطور کلی دو نوع اسمبلی وجود دارد : اسمبلی‌های خصوصی و اسمبلی‌های عمومی. در هنگام تولید اسمبلی نیازی به مشخص کردن نوع اسمبلی نیست. اسمبلی‌های خصوصی تنها برای یک برنامه قابل دسترس هستند. در این حالت اسمبلی شما بصورت یک DLL ایجاد می‌شود و در دایرکتوری مشابه با برنامه‌ای که از آن استفاده می‌کند، نصب می‌گردد. با تولید اسمبلی خصوصی (Private) تنهای برنامه‌ای که می‌تواند از اسمبلی شما استفاده کند، برنامه اجرایی است که در دایرکتوری مشابه با اسمبلی شما قرار داشته باشد.

 اما اگر بخواهید برنامه‌های متعددی از کد شما استفاده کنند، از اسمبلی عمومی (Global) استفاده می‌کنید. اسمبلی‌های عمومی توسط کلیه برنامه‌های .Net موجود بر روی سیستم قابل استفاده هستند. مایکروسافت این اسمبلی‌ها را بعنوان اسمبلی‌های .Net در نظر می‌گیرد و کلیه اسمبلی‌های .Net برای کلیه برنامه‌ها قابل استفاده هستند. .Net Framework شامل لیستی از اسمبلی‌های عمومی است که تحت عنوان global assembly cache شناخته می‌شوند و .Net Framework SDK شامل ابزارهایی جهت نصب و پاک کردن اسمبلی‌های مختلف از این دایرکتوری می‌باشد.  

کامپایل برنامه در Command Line

پس از اینکه برنامه خود را نوشتید، نوبت به کامپایل آن می‌رسد. توجه کنید که برای کامپایل برنامه‌های C# حتماً به محیط ویژوال نیازی نیست. چون دوستان بسیاری به من ایمیل زدند و درخواست کرده‌اند تا نحوه کامپایل برنامه‌ها را در Command Line را توضیح دهم، در اینجا به توضیح درباره آن پرداختم. توجه کنید که شما برای شروع کار حتی به محیطی مثل VS.Net و یا C#Builder هم نیازی ندارید. تنها کافیست تا کد برنامه خود را در یک ویرایشگر متن مانند Notepad تایپ کنید و سپس از طریق Command Line به اجرای آن بپردازید. تنها نکته‌ای که باید به آن توجه نمایید آنست که در هنگام ذخیره کردن کدی که در Notepad نوشته اید، باید به انتهای نام فایل خود پسوند .cs را اضافه نمایید.

 حال نوبت به کامپایل کد نوشته شده می‌رسد. کامپایلر Command Line بطور پیش فرض در دایرکتوری زیر وجود دارد : c:\windows\Microsoft.Net\Framework\v.xxxx تحت عنوان csc.exe قرار دارد که xxxx شماره ورژن .Net Framework نصب شده بر روی سیستم شماست. فرض کنید می‌خواهیم برنامه‌ای با نام Hello.cs را که در محیط Notepad آنرا نوشته‌ایم را کامپایل کنیم. وارد Command Line شده و عبارت csc Hello.cs را تایپ کنید. پس از این دستو در صورتیکه کد شما دارای خطا نباشد، در همان دایرکتوری موجود فایل اجرایی تحت عنوان Hello.exe تولید خواهد شد که همان برنامه کامپایل شده شماست.

نکته مهمی که باید به آن توجه کنید، وجود کامپایلر در مسیری است که فایل کد مورد نظر شما قرار دارد. برای مثال در صورتیکه csc.exe را به مسیر ویندوز اضافه نکرده باشید، برای اجرای مثال قبل باید فایل نوشته شده را در مسیر csc.exe قرار دهید و سپس از طریق Command Line آنرا اجرا نمایید. برای مثال اجرای این برنامه بر روی کامپوتر خود من بشکل زیر است. (علت اینکه گفته‌ام بر روی کامپیوتر خود من، بخاطر متفاوت بودن مسیرهای نصب برنامه بر روی کامپیوتر های مختلف است.!)

                      

 همانطور که مشاهده می‌کنید، پس از اجرای دستور گفته شده، در صورتیکه برنامه بدون خطا باشد، پیغام خطایی ظاهر نشده و فایل اجرایی برنامه تولید می‌شود.

 کدی که من برای Hello.cs در نظر گرفته بودم بصورت زیر است :

class HelloWorld

{

public static void Main()

{

System.Console.WriteLine("Hello World!");

System.Console.ReadLine();

}

}

با اجرای کد فوق فایل اجرایی آن ایجاد شده و قابل استفاده می‌گردد. در صورتیکه کد شما دارای خطا باشد، پس از کامپایل کد از طریق Command Line ، خطی از کد که خطا در آن وجود دارد با نوع خطای آن برای شما نمایش داده می‌شود.

class HelloWorld

{

public static void Main()

{

System.Console.WriteLine("Hello World!");

System.Console.ReadLine()

}

}

برای مثال در کد فوق، در خط آخر سمی کالون ";" را حذف کرده‌ام تا خطایی اتفاق افتد. خروجی کامپایلر بصورت شکل زیر در خواهد آمد.

                      

 همانطور که در شکل بالا مشاهده می‌کنید، پس از اجرای کامپایلر C#، خطایی ظاهر می‌شود که در آن نشان می‌دهد که برنامه در سطر 6 و ستون 26 دارای خطا است که این خطا عدم وجود ";" است.

 کار با کامپایلر Command Line اندکی دشوار بوده و نیاز به تمرین و اندکی تامل دارد.


استفاده از مطالب این قسمت از  سایت در هر سایت یا وبلاگ و رسانه دیگری با ذکر آدرس دقیق منبع و نام نویسنده آن بلامانع می‌باشد. تمامی حقوق مادی و  معنوی این سایت و این نوشته متعلق به شخص "میثم قزوینی" است.


منابع این مطلب :

.Net Framework SDK Release 1.1 2003
Copyright © Microsoft 2001-2003

C# Bible
Authors : Jeff Ferguson, Brian Patterson, Jason Beres,Pierre Boutquin, and Meeta Gupta
Published by : Wiley Publishing, Inc.
Copyright © 2002 by Wiley Publishing, Inc., Indianapolis, Indiana, USA
www.wiley.com

  
نویسنده : ali gooliof ; ساعت ۳:٥٩ ‎ب.ظ روز ۱۳۸٧/٢/٦
تگ ها :