التعامل مع المكتبات في سي بلاس بلاس | 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 في تطبيق الشرح و بالتالي سنشرح كيفية إضافة مكتبات خارجية بواسطته.
في حال كنت تستخدم برنامج آخر, ستخلتف قليلاً الطريقة التي تقوم فيها بتضمين المكتبة التي تنشئها في المشروع لأن كل برنامج يملك واجهة مختلفة للعمل.
الآن, بهدف جعل الشرح مبسط لأبعد حدود و يغطي كل المعلومات التي تحتاج معرفتها عند التعامل مع المكتبات, سنقوم بتقسيم المثال لأربع خطوات أساسية:
إنشاء مشروع C++ عادي لأننا سنستخدمه لتجربة المكتبة.
إنشاء مشروع آخر عبار عن المكتبة التي سنقوم بتضمينها في المشروع الأول.
إضافة المكتبة في المشروع و استدعاء الدوال الموجودة فيها.
إعادة التعديل على المكتبة و إضافة ملفات إمتدادها
.cpp
و.h
فيها مع وضع الكود بداخل نطاق ( Namespace ).
خطوات إنشاء مشروع جديد باستخدام برنامج CodeBlocks
قم باتباع الخطوات التالية بدقة لإنشاء مشروع C++ إسمه Test
.
أنقر على
File
, ثمNew
, ثمProject...
كالتالي.
أنقر على
Console application
ثم على الزرGo
كالتالي.
أنقر على
++C
و من ثم أنقر علىNext
كالتالي.
قم بتحديد الإسم الذي تريد وضعه للمشروع و مسار المجلد الذي تريد أن يتم فيه حفظه على حاسوبك, ثم أنقر على
Next
كالتالي.
لا تعدل أي شيء في هذه الصفحة و أنقر على
Finish
كالتالي.
بعد أن يتم إنشاء المشروع بنجاح سيظهر بداخل قائمة المشاريع كالتالي.
الآن قم بالعودة للدرس و انتقل للخطوة الثانية التي ستتعلم منها طريقة إنشاء المكتبة harmash
و التي ستعود لاحقاً و تضمنها في هذا المشروع.
خطوات إنشاء مكتبة ثابتة في CodeBlocks
قم باتباع الخطوات التالية بدقة لإنشاء مشروع إسمه harmash
عند بنائه ينتج مكتبة ثابتة إسمها libharmash
.
أنقر على
File
, ثمNew
, ثمProject...
كالتالي.
أنقر على
Static library
ثم على الزرGo
كالتالي.
قم بوضع علامة صح على الخيار
Skip this page next time
ثم أنقر علىNext
كالتالي حتى لا تظهر لك هذه الصفحة مرة كلما أردت إنشاء مكتبة مستقبلاً.
قم بتحديد الإسم الذي تريد وضعه للمشروع و مسار المجلد الذي تريد أن يتم فيه حفظه على حاسوبك, ثم أنقر على
Next
كالتالي.
لا تعدل أي شيء في هذه الصفحة و أنقر على
Finish
كالتالي.
بعد أن يتم إنشاء المشروع بنجاح سيظهر بداخل قائمة المشاريع كالتالي.
بما أننا نريد كتابة كود بلغة C++ و ليس بلغة C سنقوم بتغيير إمتداد الملف
main
إلى.cpp
كالتالي.
قم بتسمية الملف
main.cpp
ثم أنقر على الزرOK
كالتالي.
قم بفتح الملف
main.cpp
و حذف أي كود إفتراضي تجده فيه كالتالي.
بعدها أكتب الكود التالي بداخله لتعريف دالة إسمها
printMsg()
تقوم بطباعة جملة عادية عند استدعائها.
#include <iostream> void printMsg() { std::cout << "First time using a static library!"; }
بعد إضافة الكود في الملف
main.cpp
أنقر على زر حفظ كل التغييرات التي تم إجراءها كالتالي.
آخر خطوة يجب أن تفعلها هي النقر على زر البناء ( Build ) حتى يتم إنتاج مكتبة من المشروع كالتالي.
لاحظ أنه أخبرك أنه قد تم إنشاء مكتبة إسمهاlibharmash.a
بداخل المسارbin\Debug
في المشروع نفسه.
إذا شاهدنا ملفات المشروع من خارج برنامج CodeBlocks سنجد المكتبة libharmash.a
كالتالي.
الآن قم بالعودة للدرس و انتقل للخطوة الثالثة التي ستتعلم منها طريقة تضمين المكتبة libharmash.a
في المشروع Test
.
خطوات إضافة مكتبة في المشروع باستخدام برنامج CodeBlocks
قم باتباع الخطوات التالية بدقة لإضافة المكتبة libharmash.a
في المشروع Test
و من ثم استدعاء الدوال الموجودة في المكتبة التي تم إضافتها للتأكد من أن ذلك قد تم بنجاح.
في البداية أغلق أي ملف مفتوح حتى لا تشتت نفسك بسبب الملفات المفتوحة كالتالي.
أنقر بزر الفأرة الأيمن على إسم المشروع
Test
ثم أنقر علىBuild Options...
كالتالي.
أنقر على
Linker Settings
لأنه القسم الذي يمكنك من خلاله إضافة المكتبات في المشروع.
أنقر على الزر
Add
ثم على أيقونة المجلد حتى تبدأ بإضافة المكتبة في المشروع كالتالي.
بعد تحديد المكتبة التي تريد إضافتها - و في حالتنا المكتبة
libharmash.a
- قم بالنقر على الزرOpen
كالتالي.
أنقر على الزر
No
لحفظ مسار المكتبة الكامل ( Full Path ) كالتالي.
أنقر على الزر
Ok
كالتالي حتى يتم إضافة المكتبة.
أنقر على الزر
Ok
كالتالي حتى إغلاق النافذة أو أغلاقها بالنقر على زر الإغلاق.
أنقر بزر الفأرة الأيمن على إسم المشروع
Test
ثم أنقر علىActivate Project
كالتالي.
إفتح الملف
main.cpp
الموجود في المشروعTest
كالتالي.
أكتب الكود التالي بداخل الملف
main.cpp
حتى تستدعي الدالةprintMsg()
الموجودة في المكتبةlibharmash.a
التي ستطبع لك جملة عادية حين تتنفذ.
#include <iostream> using namespace std; // مع الإشارة إلى أنه حين يتم استدعاؤها main() حتى نتمكن من استدعائها في الدالة printMsg() هنا قمنا بذكر شكل الدالة // libharmash.a سيقوم المترجم بالبحث عن تعريفها إلى أن يجدها, و بالطبع في حالتنا سيجدها بداخل المكتبة void printMsg(); int main() { // printMsg() هنا قمنا باستدعاء الدالة printMsg(); return 0; }
أنقر على الزر
Build and run
كالتالي حتى يتم حفظ الملفmain.cpp
و من ثم بناء و تشغيل المشروعTest
.
ستظهر لك النتيجة التالية بعد أن يتم تشغيل المشروع
Test
.
الآن قم بالعودة للدرس و انتقل للخطوة الرابعة و الأخير حيث سنقوم بإضافة ملفات .cpp
و .h
و من ثم تضمينها في المشروع أيضاً Test
أيضاً.
خطوات تضمين ملفات المكتبة باستخدام برنامج CodeBlocks
قم باتباع الخطوات التالية بدقة لإضافة ملف إسمه Person.h
و ملف إسمه Person.cpp
في المشروع Harmash
.
بعدها قمنا بتضمين الملف Person.h
الموجود في المشروع Harmash
في المشروع Test
.
في النهاية قمنا باستخدام الكود الموجود في الملفات التي تم تضمينها للتأكد من ذلك قد تم بنجاح.
في البداية أغلق أي ملف مفتوح حتى لا تشتت نفسك بسبب الملفات المفتوحة كالتالي.
أنقر بزر الفأرة الأيمن على إسم المشروع
Test
ثم أنقر علىActivate Project
كالتالي.
أنقر على أيقونة إضافة ملف جديد, ثم أنقر على
Class...
كالتالي حتى تضيف كلاس جديد في المشروع بداخل ملف.cpp
خاص و معه الشكل العام للكلاس بداخل ملف.h
دفعة واحدة
قم بتسمية الكلاس
Person
ثم أنقر على الزرCreate
كالتالي حتى ينشئ لك ملف إسمهPerson.cpp
و الشكل العام له بداخل ملف إسمهPerson.h
.
أنقر على الزر
Yes
لإضافة الملفات الجديدة التي تم إنشاؤها في المشروعHarmash
كالتالي.
أنقر على الزر
Select All
ثم على الزرOK
كالتالي.
لاحظ أنه تم إنشاء الملفين
Person.cpp
وPerson.h
و بداخلهما تم تجهيز كلاس فارغ إسمهاPerson
أيضاً.
إمسح الكود الإفتراضي الموجود في الملف
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(); }; }
إمسح الكود الإفتراضي الموجود في الملف
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"; } }
أنقر على زر البناء ( Build ) حتى يتم إنتاج مكتبة من المشروع
Harmash
كالتالي.
لاحظ أنه أخبرك أنه قد تم إنشاء مكتبة إسمهاlibharmash.a
بداخل المسارbin\Debug
في المشروع نفسه, أي مكان المكتبة التي أنشأناها في السابق.
أغلق جميع الملفات المفتوحة حتى لا تربك نفسك بها.
أنقر بزر الفأرة الأيمن على إسم المشروع
Test
ثم أنقر علىBuild Options...
كالتالي.
أغلق على الزر
Search directories
كالتالي حتى تحدد مكان الملفات التابعة للمكتبةlibharmash.a
و التي تريد تضمينها في المشروعTest
أيضاً.
بداخل القسم
Compiler
أنقر على الزرAdd
كالتالي لأنك بحاجة لإعلام المترجم بمسار الملفPerson.h
الذي ستقوم لاحقاً بتضمينه في المشروعTest
.
أنقر على أيقونة المجلد حتى تبدأ بإضافة مكان وجود الملف
Person.h
كالتالي.
بعد تحديد مكان وجود الملف
Person.h
- و في حالتنا المجلدinclude
الموجود بداخل المشروعHarmash
- قم بالنقر على الزرSelect Folder
كالتالي.
أنقر على الزر
No
لحفظ مسار المجلد الكامل ( Full Path ) كالتالي.
أنقر على الزر
Ok
كالتالي حتى يتم إضافة المكتبة.
إنتقل إلى القسم
Linker
ثم أنقر على الزرAdd
و أضف نفس المسار الذي أضفته في القسمCompiler
.
بعد إضافة المسار, أنقر على الزر
Ok
كالتالي حتى إغلاق النافذة أو أغلاقها بالنقر على زر الإغلاق.
إفتح الملف
main.cpp
الموجود في المشروعTest
و إمسح كل الكود الموجود فيه كالتالي.
أكتب الكود التالي بداخل الملف
main.cpp
حتى تنشئ كائن من الكلاسPerson
و تستدعي الدالةprintInfo()
منه حتى تطبع المعلومات التي مررناها للكائن حين تتنفذ.
#include <iostream> #include <Person.h> int main() { harmash::Person p("Mhamad", "70654200"); p.printInfo(); return 0; }
أنقر بزر الفأرة الأيمن على إسم المشروع
Test
ثم أنقر علىActivate Project
كالتالي.
أنقر على الزر
Build and run
كالتالي حتى يتم حفظ الملفmain.cpp
و من ثم بناء و تشغيل المشروعTest
.
ستظهر لك النتيجة التالية بعد أن يتم تشغيل المشروع
Test
.