لغة C++/CLI لغة جديدة أصدرتها ميكروسوفت لدعم مواصفات تقنية الدوت نت (.Net) انطلاقا من لغة C المعيارية، منذ الانطلاق وحتى اليوم صاحب اللغة عديد من التطويرات والتغيرات.
لتبسيط المفاهيم الخاصة بهذه اللغة وملحقاتها، سنأخذ كود لغة C التالي:
int main()
{
printf("hello, world");
}
#include <stdio.h>
وحتى نكون دقيقين أكثر، الكود السابق ليس كود C فقط، بل هو أيضا كود من لغة C++، ذلك أن لغة C++ مشتقة أصلا من لغة C، ولها درجة توافقية أرقى من لغة C، بمعنى آخر يمكننا
في لغة C++ أن نكتب كود هو عبارة عن خليط من بنية لغة C ولغة C++ معا كما هو واضح في الكود التالي.
#include <iostream>
int main()
{
printf("hello");
std::cout<< ", world";
}
#include <stdio.h>
الفكرة تماما جاءت بها لغة C++/CLI الجديدة، فهي امتداد أرقى من لغة C++، ويمكن على مستوى أكوادها كتابة بنيات خاصة بلغة C/C++، والكود التالي يوضح هذا تماما:
[#include <stdio.h>
#include <iostream>
int main()
{
// use a C function to print "hello"
printf("hello");
// use a C++ object to print a comma followed by a space
std::cout<< ", ";
// use a .NET class to print "world"
System::Console::WriteLine("world");
}
الشيء المثير في الكود السابق أننا استخدمنا فيه الـC والـC++ والـ.Net كلها معا لبناء الدالة الرئيسية main() .
مصطلحات شائعة لا بد منها قبل البدء بـC++/CLI:
هنالك مصطلحات شائعة تتكرر في أغلب لغات بيئة العمل الجديدة (نسبيا) .Net ، نبدأ هنا بقائمة هي من أهم المصطلحات والمفاهيم التي يجب أن يعيها مبرمج C++/CLI جيدا،
ثم سنتطرق لشرحها:
• CLI
• CIL أو MSIL
• CLR
• Managed code
• Native code
مثلما هو واضح في الشكل أن هناك وسيط مشترك لجميع لغات بيئة الـ.NET تؤول إليه كلها في النهاية، هذا الوسيط المشترك يسمى بنية اللغة المشتركة
(CLI (Common Language Infrastructure، تتضمن هذه البنية عنصرين هامين، العنصر الأول هو مكوّن اللغة الوسيطية المشتركة
CIL Common Intermediate Language والمشروع المنجز من ميكروسوفت لهذا المُكوّن يدعى لغة ميكروسوفت الوسيطيةMSIL،
أما العنصر الثاني فيسمى مكوّن وقت تشغيل اللغة المشتركة CLRCommon Language Run-time.
الـمكون CLR هو عبارة عن مترجم من النوع اللحضوي JIT Just in time، أي أنه يعمل دائما وقتما يتم تشغيل البرنامج في هيئة اللغة الوسيطية المشتركة فيقوم بتحويل اللغة
الوسيطية المشتركة CIL إلى أكواد لغة الآلة يفهمها عتاد الحاسوب ويتعامل معها. لهذا يمكن إطلاق اسم الآلة الظاهرية (Virtual Machine) لهذا المكون، أي أنه وسيط بين اللغة التي
يفهمها عتاد الحاسوب وبين اللغة عالية المستوى، هذا الأسلوب يشابه تماما الفكرة المطبقة في لغة جافا وآلتها الظاهرية.
أما مصطلح الكود المُدار (Managed code) فيشير إلى تلك المجموعة من الأكواد التي أتت وطُوّرت بشكل مخصوص لتتخاطب مع بيئة إطار العمل.NET ، أما أكواد اللغات القياسية
القديمة الأخرى فتسمى بالأكواد الطبيعية (Native code) .
مُلمْلِم النفايات (Garbage Collector):
كما تم ذكره فإن لغة C++/CLI لم تقم بإحلال نفسها بديلا للغة C++ المعيارية، بل أضافت لها القدرة على إنشاء وقبول الأكواد المُدارة (managed code) والميزات التي يتمتع بها إطار
العمل.NET .
مُلملم النفايات هو أحد التقنيات التي تتمتع بها اللغة C++/CLI، بهذه التقنية لم يعد مبرمج C++ قلقا من قضية نسيانه تحرير مواقع الذاكرة التي قام بحجزها ديناميكيا، فمثلا عندما
يقوم المبرمج بإنشاء وخلق كائن (Object) بشكل ديناميكي من صنف معين (Class)، يقوم مُلملم النفايات - وهو عملية تعمل في الخلفية - بلملمة وتدمير الكائنات أي تحرير المواقع
التي تم حجزها بعد الانتهاء من وظائفها. لاحظ المثالين التاليين.
.
.
}
N* n= new N;
class N {الأعلى يمثل كود C++ معياري، قمنا فيه بخلق صنف باسم N ومن ثم قمنا بإنشاء وحجز ذاكرة لكائن يُشار له بإسم n وهو بحجم الصنف N، لاحظ أننا استخدمنا الكلمة المفتاحية
new لحجز ذاكرة للكائن في ذاكرة الكومة الطبيعية Native heap، ولتعريف المؤشر استخدمنا علامة * المعتادة.
.
.
}
M^ r= gcnew M;
ref class M {الأعلى يمثل كود ُمدار C++/CLI، قمنا فيه بالمقابل للكود السابق، لاحظ الاختلافات، حيث أننا نستخدم علامة الإقحام ^ بدلا من * ، هنا r تُسمى مقبض وليس مؤشر، ولاحظ كذلك
استخدامنا ل gcnew بدلا من new، حيث قمنا بحجر ذاكرة للكائن على ذاكرة الكومة المدارة managed heap.
كما شاهدنا في المثال، فإن gcnew هو مؤثر يقوم بحجز مساحة على ذاكرة الكومة المدارة (Managed heap)، وهذه المساحة هي حوض ذاكري يُدار بواسطة مُلملم النفايات
(Garbage collector)، ومثلما نلاحظ فإن الحرفان الأوليان من الكلمة gcnew هما اختصار لـ garbage collector.
رجوعا للمثال، يُسمى r بمقبض تتبع (tracking handle) وذلك لسببين اثنين، الأول هو أن ململم النفايات يستطيع تحرير الكائنات غير المفيدة، والثاني أن له الإمكانية كذلك في
تحريك الكائنات حول الذاكرة بهدف تنظيم الكومة تحقيقا لكفاءة مُحسنة، وهذه العملية تسمى بتكنيز الكومة (Heap compaction)، وبديهيا لن يكون هنالك عنوان ثابت للكائنات،
وعندما يقوم ململم النفايات بعملية التحريك والتنظيم يقوم مكوّن وقت التشغيل (Run time) بتحديث العناوين.
حسنا نستطيع الآن القول وبكل فخر أن مبرمج C++/CLI يستطيع العمل على نوعين من ذاكرة الكومة (Heap) هما ذاكرة الكومة الطبيعية (Native heap) وكذلك ذاكرة الكومة المُدارة (Managed heap)! لاحظ كيف تجمع C++/CLI بين قوة C++ المعيارية والميزات التي تقدمها بيئة العمل دوت نت. بقي أن نقول أن عملية الخلط هذه يجب مراعاة عدة أشياء فيها لجعل الكود يؤدي غرضه بكل أمان.
نظام النوع المشترك (Common Type System) :
بكل سهولة ودون إطالة نختصر موضوع نظام النوع المشترك بالقول أن لغات الدوت نت ومن ضمنها C++/CLI تشترك بنوع بيانات موحد في ما بينها يسمى نظام النوع المشترك أوCTS،
فمثلا النوع int في لغة C++/CLIليس إلا اسما آخر للنوع Int32الذي تشترك فيه جميع لغات الدوت نت والذي ينحدر من مجال الأسماء System كباقي الأنواع الأخرى (ٍSystem::Int32).
وإلى اللقاء في دروس أخرى.