الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

البداية مع لغة C++/CLI

بدأه A.S Hack في 3 ديسمبر 2011 · 10 رد · 3,404 مشاهدة · في C++.Net
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

لغة 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

post-87237-081573500 1322924474_thumb.pn

مثلما هو واضح في الشكل أن هناك وسيط مشترك لجميع لغات بيئة الـ.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).

وإلى اللقاء في دروس أخرى.

المرفقات
structure.png

تم تعديل هذه المشاركة بواسطة A.S Hack في 3 ديسمبر 2011 في 18:52

3

" إن الله كتب الإحسان على كل شيء"

::

الإرادة ... تحقق السيادة.

#2

معلومات رائعة

شكرا لك

#3

الصوره المرفقه بالأعلى توضح أن كلا من كود ال VB و السي شارب و ال managed CPP كلهم ينتجو نفس ال intermediate lang ..

إذن ما الفائده هنا من كتابة تطبيقى بلغه صعبه كال CPP عندما يمكن ان أستخدم لغه سهله C# أو VB.net ...

#4

__Unknown كتب:

الصوره المرفقه بالأعلى توضح أن كلا من كود ال VB و السي شارب و ال managed CPP كلهم ينتجو نفس ال intermediate lang ..

إذن ما الفائده هنا من كتابة تطبيقى بلغه صعبه كال CPP عندما يمكن ان أستخدم لغه سهله C# أو VB.net ...

سؤال جميل.

باختصار الجملة "كلهم ينتجو نفس ال intermediate lang" غير دقيقة تماماً.

لماذا؟! خذ مثالا بسيطا - وليس الوحيد -: المصفوفة...!

لغات الدوت النت تنتج MSIL لمصفوفات من نوع "مصفوفات مُدارة" أو managed array، ومن ضمنها C++/CLI.

ميزة هذا النوع من المصفوفات أنه قابل للتحقق من قبل CLR، بمعنى أن هذا النوع من المصفوفات لا يمكن أن يسبب مشاكل تعدي مناطق في الذاكرة .. الخ.

تنفرد C++/CLI بإنتاج MSIL خاص بالمصفوفات الطبيعية أو Native array ، وهذا النوع لا يمكن إنتاجه بلغات كـ #C و VB.

هذا النوع من المصفوفات لا يكون تحت رقابة CLR.

خذ مثالا هذا الكود:

void Dummy(int *a)
{
	a[5] = 15;
}

هل تستطيع تحديد نوع الكود السابق!

إذا قلت لي أنه كود C ... أقول لك أصبت... أكمل؟

إذا قلت لي هو أيضا ++C أقول لك أصبت ... أكمل؟

فإذا لم تكمل أقول لك هو أيضاً كود C++/CLI ...

وهذا نظيره في MSIL :

.method private hidebysig instance void Dummy(int32* a) cil managed
{
	.maxstack 2
	L_0000: ldarg.1  	// load the value of a pointer to the stack
	L_0001: ldc.i4.s 20  // load the number 20 (= 4 * 5) to the stack
	L_0003: add      	// add 20 to the pointer
	L_0004: ldc.i4.s 15  // load the number 15 to the stack
	L_0006: stind.i4 	// store the value of 15 at the computed address
	L_0007: ret      	// return from the method
}

ماذا يعني هذا؟! يعني إئتني بكود ++Native C وسأضمن لك أن أنفذه على إطار عمل دوت نت... ؟! ثم ماذا؟!

يعني إئتني بكل المكتبات والأصناف المكتوبة خصيصا لـ ++C وسأستخدمها بشكل طبيعي ودون تعقيد - كما هو حاصل في #C - في مشاريع Windows Forms Application .!

ما أتحدث عنه جزء بسيط جدا عن مفهوم تتميز به لغة C++/CLI هذا المفهوم يُسمى Interoperability .. وسأتحدث عنه في درس قادم.

مختصر جامع، هذه المعادلة غير صحيحة دائما:

C++/CLI MSIL = C# MSIL

1

" إن الله كتب الإحسان على كل شيء"

::

الإرادة ... تحقق السيادة.

#5

ماشاء الله يا أخى ... رد كافى و وافى جدا..

لكن ألا أترى أن تطبيقات السي++ سوف تفقد كثير من صفاتها إذا ما قمنا بتشغليها داخل ال .net framework ... (السرعه, الإنتقاليه ... و ربما غيرها) ؟

#6
__Unknown كتب:

ماشاء الله يا أخى ... رد كافى و وافى جدا..

لكن ألا أترى أن تطبيقات السي++ سوف تفقد كثير من صفاتها إذا ما قمنا بتشغليها داخل ال .net framework ... (السرعه, الإنتقاليه ... و ربما غيرها) ؟

أما المحمولية portability أو الانتقالية كما قلت، فهو مصطلح مطاط وماكر! ماذا تقول في بنية ملفات اسمها Portable Executable !؟ ما المقصود بـ Portable هنا ؟! لا يحلم أحد أن

Portable تعني أن ملفات PE الخاصة بويندوز يمكن لها أن تعمل – مباشرة – على توزيعات Linux أو أنظمة BSD ! كل ما في الأمر أنها Portable لويندوز فقط ولاصداراته الحديثة!

حسنا نرجع الآن للتطبيقات المكتوبة بلغة ++C ولنحاول أن نكتشف هل هي حقا Portable ؟!

لنسأل أي شخص في العالم: هاتِ لنا برنامج "عملي" كتبته بلغة ++C بشرط أن يكون ذا قيمة وفائدة للمستخدم، و بشرط آخر وهو أن يعمل البرنامج على ويندوز وتوزيعات

لينوكس(مباشرة)! حسنا دعنا نرى الاحتمالات:

إذا قام الشخص بترجمة برنامجه على ويندوز، فسينتج لنا في أغلب الحالات ملف ببنية PE وهي بنية خاصة بويندوز، وبالتالي لن تعمل على توزيعات لينوكس – مباشرة- . ... هذه

واحدة وفشل فيها الشخص.

إذا قام الشخص بترجمة برنامجه على أوبنتو مثلا، فسينتج لنا في أغلب الحالات ملف ببنية ELF وهي بنية خاصة بأنظمة Unix-like، وبالتالي لن يعمل برنامجه على ويندوز – مباشرة-

. ... هذه الثانية وفشل فيها.

قرّر الشخص أن يعطينا الكود المصدر، وليس الملف التنفيذي لبرنامجه، وقال لنا حيث شئتم أن تعملوا، ترجموا هذا الكود على نظامكم الذي تعملون عليه وسيعمل !

سنقول له قِف وتريث!!؟

وسنسأله: إذا كان برنامجك فعلا سيقبل أن يترجم ويعمل على ويندوز وأوبنتو، فهذا يعني أنك لم تكتب دالة API واحدة فيه! فكيف لبرنامج "عملي" و "ذا قيمة" كيف به ألا يستدعي دالة

API واحدة في سطوره! بالتالي لقد أخل بشرط أن يكون برنامجه فعلا "عملي". .... هذه الثالثة وفشل فيها!؟

فأين المحمولية في التطبيقات المكتوبة بلغة ++C ؟!

دعنا نفترض أن الحدود التي نتكلم فيها هي أجهزة ويندوز فقط، أقول لك هنا نعم سيعمل التطبيق في أي جهاز غالبا، ولا يحتاج لاطار عمل دوت نت.

ولكن أيضا الآن كل أجهزة ويندوز الحديثة تأتي مجهزة بإطار الدوت نت دون أن يحتاج المستخدم لتثبيته بنفسه.. بالتالي لن يفرق عندنا في هذا الحال سواء كان البرنامج مكتوب بـ++C

أم بـ C++/CLI. (من ناحية المحمولية).

من ناحية السرعة... بإختصار: C++/CLI لها سرعة إنتاجية productivity أعلى من ++C ، لأنها تستخدم أصناف الدوت نت العادية، يعني كأنك تبرمج على #C، وبالطبع ++C ستنتج

برامج أسرع، ولكن ...

تخيل أنك تريد عمل واجهة بها الكثير مما يمكن أن تختصره لو استخدمت أصناف الدوت نت، وفي نفس الوقت عندك دالة مكتوبة بـ++C ولا تريد أن تخسر كفاءتها وسرعتها... C++/CLI

توفر لك الحل بكل سهولة كيف!؟

نفرض أن الدالة هي: EfficientFunction()

في كود C++/CLI نكتبها بهذه الطريقة:

#pragma unmanaged
EfficientFunction(){
bla bla
bla
}
#pragma managed

بهذا.. حينما يتم استدعاء الدالة ستنفذ خارج إطار MSIL والدوت نت، كما لو أنها كود دالة مكتوبة ب++C تماما.. يعني لن نفقد سرعتها ولا كفاءتها...!!!!!!!

1

" إن الله كتب الإحسان على كل شيء"

::

الإرادة ... تحقق السيادة.

#7

جميل جدا ً

ماهو المترجم الخاص بهذه اللغة , هل هو الفيجول ستديو !!

M.B.O

Mohamed Bin Othman

إبن المكلا

يابني البشر ماذا فعلتم بالبشر !!

إسـألـنـي

#8

بارك الله فيك ....

#9

مبدئيا ... أنا أستمتع جدا بالنقاش معك و التعلم منك ...

بالنسبه للمحموليه:

هل تريد أن تقول أنا برامج كل FireFox و Chrome و Pidgin و Qt Creator و Code::blocks و Adobe reader و Apache server و غيرها الكثير و الكثر ..

هل تريد أن تقول أن هناك منها عدة نسخ من الصفر .. نسخه للويندوز و أخري للينوكس و أخري للماك؟

ما أعرفه أن Frameworks مثل Qt توفر لك إنتقاليه عاليه جدا - لا أعرف لأي مدي ( على مستوى ال Source code طبعا و ليس الملف الثنائى )..

أعتقد أنه زمن المقوله التي تقول "لم أحتاج ال portability لبرنامج صمم خصيصا ليعمل على لينوكس" قد إنتهى ...

فأنا أحتاج ال portability و إن كانت بنسبه معقوله ... فلا أقول 100%

منذ فتره إطلعت على ال soruce code الخاص ب Putty على ما أتذكر ... و هو برنامج عميل FTP و عدة بروتوكولات أخري ... و كان لابد أن يستخدم WIN API للويندوز و POSIX لأنظمة اليونكس و بالفعل كان يفعل ذلك بإستخدام ال macors في وقت ما قبل الترجمه ..

أما C++/CLI فأعتقد أنها تقدم 0% portability ... أليس كذلك؟

حتى أن C# الأن و بعد وجود Mono تقدم نسبة من ال portability

أما بالنسبة للسرعه:

فأنا لا أتكلم عن سرعة الإنتاجيه ... أقصد سرعة عمل البرنامج ..

جميل جدا الكلام الذي أوردته ... و لكن أليس عمل البرنامج ككل داخل ال VM الخاصه بالدوت نيت سوف يؤدي لبطئة ... و إن كان ال JIT compilers تحد من هذا البطء ولكن أعتقد أنه لن يكون بسرعة ال binary executables ..

إذن سؤالى هو ...

لم لا أستخدم C# و إن أردت تنفيذ جزء من الكود بسرعه عاليه أستخدم native calls ل مكتبات مكتوبه ب C/C++ ... ؟

تم تعديل هذه المشاركة بواسطة __Unknown في 5 ديسمبر 2011 في 15:41

#10
M.B.O كتب:

جميل جدا ً

ماهو المترجم الخاص بهذه اللغة , هل هو الفيجول ستديو !!

نعم مترجم C++/CLI ملحق ببيئة التطوير MS Visual Studio.smile.gif

" إن الله كتب الإحسان على كل شيء"

::

الإرادة ... تحقق السيادة.

#11

أخي هويدي لي عودة على كلامك. فقط انشغلت ببعض الأشياء رغما عني.wink.gif

" إن الله كتب الإحسان على كل شيء"

::

الإرادة ... تحقق السيادة.

مواضيع مشابهة