التعامل مع المكتبات في سي بلاس بلاس | C++ Database

التعامل مع المكتبات في سي بلاس بلاس | C++ Database

مفهوم المكتبات البرمجية في C++

المكتبة ( Library ) عبارة عن ملف يمكن أن يحتوي على كلاسات و دوال جاهزة بمجرد تضمينها في المشروع تصبح قادر على استخدام كل ما هو موجود فيها و كأنها جزء من المشروع. في العادة عندما يجد المطور نفسه دائماً ما يستخدم نفس الكلاسات و الدوال في مشاريعه يقوم بوضعهم بداخل مكتبة واحدة و كلما احتاج إليها يقوم بتضمينها في مشروعه.

الآن, عليك معرفة أنه يوجد نوعين من المكتبات التي يمكن تضمينها في المشروع:

  • مكتبات ثابتة ( Static Libraries ) و يكون امتدادها .lib على نظام ويندوز و .a على نظامي لينكس و ماك.

  • مكتبات ديناميكية ( Dynamic Libraries ) و يكون امتدادها .dll على نظام ويندوز و .so على نظامي لينكس و ماك.

المكتبة التي تنشئها بنفسك أو التي تقوم بتحميلها من النت, يمكنك وضعها في أي مكان تريد على حاسوبك و نقصد بذلك أنك لست مجبر على وضع المكتبات في مكان محدد حتى يسمح لك باستخدامها. لاحقاً عند الحاجة لاستخدام المكتبة في أي مشروع, يجب إعلام المترجم بمكان وجودها حتى تصبح قادراً على تضمين أي ملف موجود فيها و البدء باستخدام الكود الموجود فيه.

الأفضل و الأسهل لك دائماً هو أن تخصص مكان في حاسوبك تضع فيه كل المكتبات التي قد تستخدمها.

أهمية بناء المشروع أو المكتبة في C++

من بداية الدورة و حتى الآن كنا نقوم دائماً النقر على الزر Build and run عندما نريد تشغيله و ليس فقط الزر Run, بمعنى آخر كنا نبني المشروع قبل بنائه.

الصورة التالية تذكرك بأسماء الأزرار التي نستخدمها في برنامج CodeBlocks لبناء و تشغيل المشروع.

المقصود من بناء المشروع هو قيام المترجم بالتأكد من أن كود المشروع لا يوجد فيه أي مشكلة من ناحية كتابة الأوامر (Syntax Error) و من ثم تحويل كل كود المشروع (Compile) لملف تنفيذي إمتداده .exe.

المقصود من تشغيل المشروع, هو تشغيل الملف التنفيذي الذي يمثل البرنامج النهائي الناتج عن عملية بناء المشروع فقط.


الفرق بين الحفظ (Save) و البناء (Build)

حفظ ملفات المشروع يعني حفظ الكود الذي تم كتابته فيها فقط.
بالتالي في حال قمت بحفظ ملفات المشروع فقط بدون بنائها سيظهر لك دائماً نتيجة آخر بناء فعلته عند التشغيل.


نقطة البداية في المكتبة

عندما نقوم بتجهيز مكتبة فنحن بذلك نقوم بتجهيز كود يمكن تضمينه في المشاريع و ليس كود عبارة عن برنامج بحد ذاته.
لهذا السبب المكتبة لا يفترض أن نضع فيها دالة إسمها main() نعتبرها كنقطة بداية كما نفعل في المشاريع العادية.

عدم وجود نقطة بداية في المكتبة معناها أنه يمكنك أن تفعل Build لها فقط و ليس Run لأنها بحد ذاتها ليست برنامجاً يمكن تشغيله.


أهمية بناء المكتبة بعد إجراء أي تحديث عليها

إعادة بناء المكتبة بعد أن تنتهي من كتابة الكود الخاص فيها في كل مرة من خلال النقر على على الزر Build أمر مهم جداً لكي يتم إنتاج نسخة جديدة من المكتبة نوعها .lib أو .a أو .dll أو .so على حسب نوع المكتبة (Static أو Dynamic) و نوع نظام التشغيل الذي تبني المكتبة عليه كما ذكرنا سابقاً.

الفرق بين المكتبات الثابتة و المكتبات الديناميكية في C++

من ناحية التعامل مع الكود الموجود في المكتبات سواء كنت تستخدم مكتبة ثابتة أو مكتبة ديناميكية فإنه لا يوجد إي إختلاف من هذه الناحية.

الإختلاف الأساسي بين النوعين هو أن المكتبات الثابتة يتم دمج الكود الموجودة فيها مع كود المشروع نفسه حين تقوم ببناء المشروع. في حين أن المكتبات الديناميكية تظل موضوعة بشكل منفصل عن كود المشروع حين تقوم ببنائه.

في كل مرة تقوم فيها بإجراء تعديل على كود مكتبة ثابتة تستخدمها في مشروعك, يجب إعادة بناء كود المكتبة و من ثم كود المشروع الذي يستخدمها لجعل المشروع يستخدم آخر نسخة تم تحديثها من منها. أما في حال إجراء تعديل على كود مكتبة ديناميكية في مشروعك, يجب إعادة بناء كود المكتبة فقط بدون الحاجة لإعادة بناء كود المشروع.


معلومة تقنية

أحياناً عندما تحاول تشغيل برنامج ما على حاسوبك يظهر لك خطأ يخبرك بأنه يوجد ملف .dll ناقص يحتاجه البرنامج حتى يشتغل كالتالي.

هذا الخطأ معناه بكل بساطة أن البرنامج الذي تستخدمه في الأساس يستخدم المكتبة الديناميكية MSVCR71.dll التي تم ذكر إسمها و التي لم يستطع إيجادها.

لحل هذه المشكلة في العادة تقوم بالبحث في النت عن إسم الملف المذكور (أي المكتبة) الذي يحتاجه التطبيق حتى يعمل.
في حالتنا نبحث عن الملف MSVCR71.dll و بعد إيجاده نقوم بإضافته في ضمن ملفات البرنامج فقط.

طريقة إنشاء مكتبة و استخدامها في C++

في البداية نود الإشارة إلى أننا نستخدم برنامج CodeBlocks في تطبيق الشرح و بالتالي سنشرح كيفية إضافة مكتبات خارجية بواسطته.
في حال كنت تستخدم برنامج آخر, ستخلتف قليلاً الطريقة التي تقوم فيها بتضمين المكتبة التي تنشئها في المشروع لأن كل برنامج يملك واجهة مختلفة للعمل.

الآن, بهدف جعل الشرح مبسط لأبعد حدود و يغطي كل المعلومات التي تحتاج معرفتها عند التعامل مع المكتبات, سنقوم بتقسيم المثال لأربع خطوات أساسية:

  1. إنشاء مشروع C++ عادي لأننا سنستخدمه لتجربة المكتبة.

  2. إنشاء مشروع آخر عبار عن المكتبة التي سنقوم بتضمينها في المشروع الأول.

  3. إضافة المكتبة في المشروع و استدعاء الدوال الموجودة فيها.

  4. إعادة التعديل على المكتبة و إضافة ملفات إمتدادها .cpp و .h فيها مع وضع الكود بداخل نطاق ( Namespace ).



خطوات إنشاء مشروع جديد باستخدام برنامج CodeBlocks

قم باتباع الخطوات التالية بدقة لإنشاء مشروع C++ إسمه Test.

  1. أنقر على File, ثم New, ثم Project... كالتالي.


  1. أنقر على Console application ثم على الزر Go كالتالي.


  1. أنقر على ++C و من ثم أنقر على Next كالتالي.


  1. قم بتحديد الإسم الذي تريد وضعه للمشروع و مسار المجلد الذي تريد أن يتم فيه حفظه على حاسوبك, ثم أنقر على Next كالتالي.


  1. لا تعدل أي شيء في هذه الصفحة و أنقر على Finish كالتالي.


  1. بعد أن يتم إنشاء المشروع بنجاح سيظهر بداخل قائمة المشاريع كالتالي.


الآن قم بالعودة للدرس و انتقل للخطوة الثانية التي ستتعلم منها طريقة إنشاء المكتبة harmash و التي ستعود لاحقاً و تضمنها في هذا المشروع.

خطوات إنشاء مكتبة ثابتة في CodeBlocks

قم باتباع الخطوات التالية بدقة لإنشاء مشروع إسمه harmash عند بنائه ينتج مكتبة ثابتة إسمها libharmash.

  1. أنقر على File, ثم New, ثم Project... كالتالي.


  1. أنقر على Static library ثم على الزر Go كالتالي.


  1. قم بوضع علامة صح على الخيار Skip this page next time ثم أنقر على Next كالتالي حتى لا تظهر لك هذه الصفحة مرة كلما أردت إنشاء مكتبة مستقبلاً.


  1. قم بتحديد الإسم الذي تريد وضعه للمشروع و مسار المجلد الذي تريد أن يتم فيه حفظه على حاسوبك, ثم أنقر على Next كالتالي.


  1. لا تعدل أي شيء في هذه الصفحة و أنقر على Finish كالتالي.


  1. بعد أن يتم إنشاء المشروع بنجاح سيظهر بداخل قائمة المشاريع كالتالي.


  1. بما أننا نريد كتابة كود بلغة C++ و ليس بلغة C سنقوم بتغيير إمتداد الملف main إلى .cpp كالتالي.


  1. قم بتسمية الملف main.cpp ثم أنقر على الزر OK كالتالي.


  1. قم بفتح الملف main.cpp و حذف أي كود إفتراضي تجده فيه كالتالي.


  1. بعدها أكتب الكود التالي بداخله لتعريف دالة إسمها printMsg() تقوم بطباعة جملة عادية عند استدعائها.

main.cpp
	  #include <iostream>

	  void printMsg()
	  {
	  std::cout << "First time using a static library!";
	  }
	

  1. بعد إضافة الكود في الملف main.cpp أنقر على زر حفظ كل التغييرات التي تم إجراءها كالتالي.


  1. آخر خطوة يجب أن تفعلها هي النقر على زر البناء ( Build ) حتى يتم إنتاج مكتبة من المشروع كالتالي.
    لاحظ أنه أخبرك أنه قد تم إنشاء مكتبة إسمها libharmash.a بداخل المسار bin\Debug في المشروع نفسه.


إذا شاهدنا ملفات المشروع من خارج برنامج CodeBlocks سنجد المكتبة libharmash.a كالتالي.


الآن قم بالعودة للدرس و انتقل للخطوة الثالثة التي ستتعلم منها طريقة تضمين المكتبة libharmash.a في المشروع Test.



خطوات إضافة مكتبة في المشروع باستخدام برنامج CodeBlocks

قم باتباع الخطوات التالية بدقة لإضافة المكتبة libharmash.a في المشروع Test و من ثم استدعاء الدوال الموجودة في المكتبة التي تم إضافتها للتأكد من أن ذلك قد تم بنجاح.

  1. في البداية أغلق أي ملف مفتوح حتى لا تشتت نفسك بسبب الملفات المفتوحة كالتالي.


  1. أنقر بزر الفأرة الأيمن على إسم المشروع Test ثم أنقر على Build Options... كالتالي.


  1. أنقر على Linker Settings لأنه القسم الذي يمكنك من خلاله إضافة المكتبات في المشروع.


  1. أنقر على الزر Add ثم على أيقونة المجلد حتى تبدأ بإضافة المكتبة في المشروع كالتالي.


  1. بعد تحديد المكتبة التي تريد إضافتها - و في حالتنا المكتبة libharmash.a - قم بالنقر على الزر Open كالتالي.


  1. أنقر على الزر No لحفظ مسار المكتبة الكامل ( Full Path ) كالتالي.


  1. أنقر على الزر Ok كالتالي حتى يتم إضافة المكتبة.


  1. أنقر على الزر Ok كالتالي حتى إغلاق النافذة أو أغلاقها بالنقر على زر الإغلاق.


  1. أنقر بزر الفأرة الأيمن على إسم المشروع Test ثم أنقر على Activate Project كالتالي.


  1. إفتح الملف main.cpp الموجود في المشروع Test كالتالي.


  1. أكتب الكود التالي بداخل الملف main.cpp حتى تستدعي الدالة printMsg() الموجودة في المكتبة libharmash.a التي ستطبع لك جملة عادية حين تتنفذ.

main.cpp
	  #include <iostream>

	  using namespace std;

	  // مع الإشارة إلى أنه حين يتم استدعاؤها main() حتى نتمكن من استدعائها في الدالة printMsg() هنا قمنا بذكر شكل الدالة
	  // libharmash.a سيقوم المترجم بالبحث عن تعريفها إلى أن يجدها, و بالطبع في حالتنا سيجدها بداخل المكتبة
	  void printMsg();

	  int main()
	  {
	  // printMsg() هنا قمنا باستدعاء الدالة
	  printMsg();
	  return 0;
	  }
	

  1. أنقر على الزر Build and run كالتالي حتى يتم حفظ الملف main.cpp و من ثم بناء و تشغيل المشروع Test.


  1. ستظهر لك النتيجة التالية بعد أن يتم تشغيل المشروع Test.


الآن قم بالعودة للدرس و انتقل للخطوة الرابعة و الأخير حيث سنقوم بإضافة ملفات .cpp و .h و من ثم تضمينها في المشروع أيضاً Test أيضاً.



خطوات تضمين ملفات المكتبة باستخدام برنامج CodeBlocks

قم باتباع الخطوات التالية بدقة لإضافة ملف إسمه Person.h و ملف إسمه Person.cpp في المشروع Harmash.
بعدها قمنا بتضمين الملف Person.h الموجود في المشروع Harmash في المشروع Test.
في النهاية قمنا باستخدام الكود الموجود في الملفات التي تم تضمينها للتأكد من ذلك قد تم بنجاح.

  1. في البداية أغلق أي ملف مفتوح حتى لا تشتت نفسك بسبب الملفات المفتوحة كالتالي.


  1. أنقر بزر الفأرة الأيمن على إسم المشروع Test ثم أنقر على Activate Project كالتالي.


  1. أنقر على أيقونة إضافة ملف جديد, ثم أنقر على Class... كالتالي حتى تضيف كلاس جديد في المشروع بداخل ملف .cpp خاص و معه الشكل العام للكلاس بداخل ملف .h دفعة واحدة


  1. قم بتسمية الكلاس Person ثم أنقر على الزر Create كالتالي حتى ينشئ لك ملف إسمه Person.cpp و الشكل العام له بداخل ملف إسمه Person.h.


  1. أنقر على الزر Yes لإضافة الملفات الجديدة التي تم إنشاؤها في المشروع Harmash كالتالي.


  1. أنقر على الزر Select All ثم على الزر OK كالتالي.


  1. لاحظ أنه تم إنشاء الملفين Person.cpp و Person.h و بداخلهما تم تجهيز كلاس فارغ إسمها Person أيضاً.


  1. إمسح الكود الإفتراضي الموجود في الملف Person.h و أكتب الكود التالي فيه.

Person.h
	  #pragma once

	  #include <iostream>

	  namespace harmash
	  {
	  class Person
	  {
	  public:
	  std::string name;
	  std::string phone;

	  Person(std::string name, std::string phone);

	  void printInfo();
	  };
	  }
	

  1. إمسح الكود الإفتراضي الموجود في الملف Person.cpp و أكتب الكود التالي فيه.

Person.cpp
	  #include "Person.h"

	  namespace harmash
	  {
	  Person::Person (std::string name, std::string phone)
	  {
	  this->name = name;
	  this->phone = phone;
	  }

	  void Person::printInfo()
	  {
	  std::cout << "name: " << name << "\n";
	  std::cout << "phone: " << phone << "\n";
	  }
	  }
	

  1. أنقر على زر البناء ( Build ) حتى يتم إنتاج مكتبة من المشروع Harmash كالتالي.
    لاحظ أنه أخبرك أنه قد تم إنشاء مكتبة إسمها libharmash.a بداخل المسار bin\Debug في المشروع نفسه, أي مكان المكتبة التي أنشأناها في السابق.


  1. أغلق جميع الملفات المفتوحة حتى لا تربك نفسك بها.

  2. أنقر بزر الفأرة الأيمن على إسم المشروع Test ثم أنقر على Build Options... كالتالي.


  1. أغلق على الزر Search directories كالتالي حتى تحدد مكان الملفات التابعة للمكتبة libharmash.a و التي تريد تضمينها في المشروع Test أيضاً.


  1. بداخل القسم Compiler أنقر على الزر Add كالتالي لأنك بحاجة لإعلام المترجم بمسار الملف Person.h الذي ستقوم لاحقاً بتضمينه في المشروع Test.


  1. أنقر على أيقونة المجلد حتى تبدأ بإضافة مكان وجود الملف Person.h كالتالي.


  1. بعد تحديد مكان وجود الملف Person.h - و في حالتنا المجلد include الموجود بداخل المشروع Harmash - قم بالنقر على الزر Select Folder كالتالي.


  1. أنقر على الزر No لحفظ مسار المجلد الكامل ( Full Path ) كالتالي.


  1. أنقر على الزر Ok كالتالي حتى يتم إضافة المكتبة.


  1. إنتقل إلى القسم Linker ثم أنقر على الزر Add و أضف نفس المسار الذي أضفته في القسم Compiler.


  1. بعد إضافة المسار, أنقر على الزر Ok كالتالي حتى إغلاق النافذة أو أغلاقها بالنقر على زر الإغلاق.


  1. إفتح الملف main.cpp الموجود في المشروع Test و إمسح كل الكود الموجود فيه كالتالي.


  1. أكتب الكود التالي بداخل الملف main.cpp حتى تنشئ كائن من الكلاس Person و تستدعي الدالة printInfo() منه حتى تطبع المعلومات التي مررناها للكائن حين تتنفذ.

main.cpp
	  #include <iostream>
	  #include <Person.h>

	  int main()
	  {
	  harmash::Person p("Mhamad", "70654200");

	  p.printInfo();

	  return 0;
	  }

	

  1. أنقر بزر الفأرة الأيمن على إسم المشروع Test ثم أنقر على Activate Project كالتالي.


  1. أنقر على الزر Build and run كالتالي حتى يتم حفظ الملف main.cpp و من ثم بناء و تشغيل المشروع Test.


  1. ستظهر لك النتيجة التالية بعد أن يتم تشغيل المشروع Test.