كيفية تصميم مكتبة برمجية على لغة الـ C++ 6

    • كيفية تصميم مكتبة برمجية على لغة الـ C++ 6


      بسم الله الرحمن الرحيم
      السلام عليكم و رحمة الله

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



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

      و أبدء معكم بالشرح
      الجزء الأول عمل مشروع لمكتبة برمجية على محرر لغة C++ 6
      الشرح بالصور لهذه العملية فهي بسيطة و سهلة لمن سبق له
      واستخدم هذا المحرر







      Windows Sockets
      msdn.microsoft.com/en-us/library/aa280724.aspx
      Automation
      msdn.microsoft.com/en-us/library/dt80be78(VS.80).aspx











      نلاحض بأنننا سنقوم بتصميم مكتبـة إرتباط حيـوي بالمشاركـة مـع المكتبـة البرمجيـة
      المشهورة MFC حيث ستشمـل المكتبة المصمـمة طبقات و مـيزات أم أف سي و من
      ميزات المكتبة البرمجية هووه إمكانية الإرتباط بها و استخدام وظائفها و عملياتها لأكثر
      من تطبيق برمجي في نفس الـوقـت أيضا عـادتا ما تحتـوي المـكتبات البرمـجية عـلى
      وظائف تقوم بعمليات معقدة وصعبة يمكن لمبرمج أخر من توظيفها في عمليات برمجية
      عنـد تصميم برنامـج مـا و كـما و يمـكن الإتصال بالمكتبـة البرمجيـة عن طـريق عـدة لغات
      برمجية مختلفة و يعتمد ذالك على دعم هذه اللغة للمكتبات البرمجية وأنواعها المتعددة
      و من ميزات المكتابات البرمجية تقليص مساحة الذاكـرة المستخدمـة على البرنامـج بما
      يزيد من سرعته وكفائته وأيضا لوكنا سنصمم برنامج يشمل على أغراض مختلفة ومتعددة
      تستدعي ألاف الوظائف وكل غرض من هذاالبرنامج يستدعي وظائف محددة لا يستدعيها
      الغرض الأخر أو بمعنى أخر "مستخدم يحتاج استخدامه لوظائف محددة و لا يحتاج لهذه
      الوظائف إستخدام مستخدم أخر" فالمكتبة البرمجية ستكون ذا فائدة كبيرة في وضع كهذا
      الوضع حيث لن نحتاج لتضمين البرنامج عمليات برمجية تشملها ألف وظيفة بل سنقوم بعمل
      مكتبة برمجية تشمل هذه الوظائف و نكتفي على البرنامج بأسطر أوامر تتصل بالمكتبة
      البرمجية لستخدام الوظائف و التي نحتاجها و أيضا تدخل المكتبات البرمجية في ترقية
      البرامج و إضافة ما هووه جديد عن طريق مثلا إستبدال مكتبة الإرتباط الحيوي بمكتبة
      أخرى أحدث منها


      - الجزء الثاني اعداد المكتبة البرمجية

      نبداء بالشرح

      من بعد أن قمنا بالقيام بمشروع مكتبة إرتباط حيوي و نحن الآن نعمل على الملف

      MFC_DLL_LIBRARY.cpp

      وهذا كود لمحتوى الملف كاملا

      PHP كود المصدر

      1. le="color: #000000"><?php // MFC_DLL_LIBRARY.cpp : Defines the initialization routines for the DLL.//#include "stdafx.h"#include <afxdllx.h>#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif#ifdef MFC_DLL_LIBRARYDLL_EXPORTS#define MFC_DLL_LIBRARYDLL_API __declspec(dllexport)#else#define MFC_DLL_LIBRARYDLL_API __declspec(dllimport)#endif#ifdef __cplusplusextern "C"{#endifMFC_DLL_LIBRARYDLL_API int AfxMsBox(LPCTSTR);MFC_DLL_LIBRARYDLL_API int CString_Find(int,LPSTR ,LPSTR);MFC_DLL_LIBRARYDLL_API LPSTR CString_Insert(int,LPSTR,LPSTR);MFC_DLL_LIBRARYDLL_API int CString_Get_Length(LPSTR);MFC_DLL_LIBRARYDLL_API LPSTR CString_Replace(LPSTR,LPCTSTR,LPCTSTR);#ifdef __cplusplus}#endifstatic AFX_EXTENSION_MODULE MFC_DLL_LIBRARYDLL = { NULL, NULL };extern "C" int APIENTRYDllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved){ // Remove this if you use lpReserved UNREFERENCED_PARAMETER(lpReserved); if (dwReason == DLL_PROCESS_ATTACH) { TRACE0("MFC_DLL_LIBRARY.DLL Initializing!\n"); // Extension DLL one-time initialization if (!AfxInitExtensionModule(MFC_DLL_LIBRARYDLL, hInstance)) return 0; // Insert this DLL into the resource chain // NOTE: If this Extension DLL is being implicitly linked to by // an MFC Regular DLL (such as an ActiveX Control) // instead of an MFC application, then you will want to // remove this line from DllMain and put it in a separate // function exported from this Extension DLL. The Regular DLL // that uses this Extension DLL should then explicitly call that // function to initialize this Extension DLL. Otherwise, // the CDynLinkLibrary object will not be attached to the // Regular DLL's resource chain, and serious problems will // result. new CDynLinkLibrary(MFC_DLL_LIBRARYDLL); } else if (dwReason == DLL_PROCESS_DETACH) { TRACE0("MFC_DLL_LIBRARY.DLL Terminating!\n"); // Terminate the library before destructors are called AfxTermExtensionModule(MFC_DLL_LIBRARYDLL); } return 1; // ok}int AfxMsBox(LPCTSTR TXT1){if (AfxMessageBox(TXT1)) {return 1;}return 0;}int CString_Find(int nStart ,LPSTR FSTR ,LPSTR FSUBSTR){return CString(FSTR).Find(FSUBSTR,nStart);}LPSTR CString_Insert(int nIndex ,LPSTR ISTR ,LPSTR ISUBSTR){CString ISTR2 = ISTR;ISTR2.Insert(nIndex,ISUBSTR);return (LPSTR) ISTR2.GetBuffer(ISTR2.GetLength());}int CString_Get_Length(LPSTR GLSTR){return CString(GLSTR).GetLength();}LPSTR CString_Replace(LPSTR RSTR, LPCTSTR ipszOld , LPCTSTR ipszNew){CString RSTR2 = RSTR;RSTR2.Replace(ipszOld,ipszNew);return (LPSTR) RSTR2.GetBuffer(RSTR2.GetLength());}
      عرض الكل

      أولا سنقوم بإعداد المكتبة البرمجية حتى يمكنها إستقبال الإتصال و أيضا تضمين
      ميزة الإتصال بها عن طريق لغة السي بلس و باقي اللغات

      PHP كود المصدر

      1. le="color: #000000"><?php #ifdef MFC_DLL_LIBRARYDLL_EXPORTS#define MFC_DLL_LIBRARYDLL_API __declspec(dllexport)#else#define MFC_DLL_LIBRARYDLL_API __declspec(dllimport)#endif


      يتضح من هذه العملية بأن هناك نوعين من الإتصال بمكتبة الإرتباط الحيوي و ما يحدد نوع
      الإتصال هووه طريقة الإتصال التي تصدر من التطبيق و الذي يستخدم هذه المكتبة و هذه
      بعض من طرق الإتصال بمكتبات الإرتباط الحيوي

      PHP كود المصدر

      1. le="color: #000000"><?php HMODULE HMO = LoadLibrary(_T("MFC_DLL_LIBRARY.dll"));

      / أولا أمر تحميل أو رفع المكتبة البرمجية

      PHP كود المصدر

      1. le="color: #000000"><?php typedef int (*parameters) (int,LPSTR,LPSTR);

      / ثانيا نقوم بعمل struct يطابق أنواع متغيرات الوظيفة و ترتيبها

      PHP كود المصدر

      1. le="color: #000000"><?php parameters Proc = (parameters) GetProcAddress(HMO,_T("CString_Find"));

      msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx
      /ثالثا نقوم باستجلاب عنوان الوظيفة الموجودة على المكتبة البرمجية و التي تظهر باسم
      /CString_Find

      PHP كود المصدر

      1. le="color: #000000"><?php Proc( nStart ,FSTR,FSUBSTR);

      /من بعد نقوم باتصال عادي بالوظيفة

      نوع أخر من أنواع الإتصال بالمكتبات البرمجية تاليا

      PHP كود المصدر

      1. le="color: #000000"><?php [DllImport('MFC_DLL_LIBRARY.dll', CharSet = CharSet.Unicode)] public static extern int CString_Find(int nStart ,LPSTR FSTR ,LPSTR FSUBSTR);


      و كما نلاحض بأن لكل النوعين من الإتصال كلمة محجوزة أو مفتاحية
      أو أساسية تختص به

      النوع الأول
      تختص به الكلمة المحجوزة التالية

      PHP كود المصدر

      1. le="color: #000000"><?php __declspec(dllexport)

      msdn.microsoft.com/en-us/library/a90k134d(VS.80).aspx

      و النوع الثاني
      تختص به الكلمة المحجوزة التالية

      PHP كود المصدر

      1. le="color: #000000"><?php __declspec(dllimport)

      msdn.microsoft.com/en-us/library/3y1sfaz2(VS.80).aspx


      MFC_DLL_LIBRARYDLL_EXPORTS

      هذا الجزء التالي
      MFC_DLL_LIBRARYDLL
      اسم مكتبة الإرتباط الحيوي

      _EXPORTS
      تصنف على أنها أحد خصائص وصلات مكتبات الإرتباط الحيوي
      Linker Options
      msdn.microsoft.com/en-us/library/y0zzbyt4(VS.71).aspx
      وهي ما تميز بين نوعية إتصال و أخر بمكتبة الإرتباط الحيوي

      و بهذه الدالة الشرطية يمكن للمكتبة أن تعمل على النوعين من الإتصال
      و طبعا بلإمكان جعل المكتبة البرمجية تعمل نوع واحد محدد من الإتصال
      كمثالا هذه الطريقة

      PHP كود المصدر

      1. le="color: #000000"><?php #define MFC_DLL_LIBRARYDLL_API __declspec(dllexport)

      لوحدها

      أو بهذه الطريقة

      PHP كود المصدر

      1. le="color: #000000"><?php #define MFC_DLL_LIBRARYDLL_API __declspec(dllexport)

      لوحدها

      أي جعلنا قيمة المتغير
      MFC_DLL_LIBRARYDLL_API
      مساوية لقيمة الكلمة المحجوزة أو الأساسية و التي تناسب
      نوعية الإتصال لكي نقوم فيما بعد باستخدام هذا المتغير


      - جعل مكتبة الإرتباط الحيوي تستقبل الإتصال بوظائفها من جميع
      اللغات البرمجية المتاحة بمافيها الـ C++

      PHP كود المصدر

      1. le="color: #000000"><?php #ifdef __cplusplusextern "C"{#endifMFC_DLL_LIBRARYDLL_API int AfxMsBox(LPCTSTR);MFC_DLL_LIBRARYDLL_API int CString_Find(int,LPSTR ,LPSTR);MFC_DLL_LIBRARYDLL_API LPSTR CString_Insert(int,LPSTR,LPSTR);MFC_DLL_LIBRARYDLL_API int CString_Get_Length(LPSTR);MFC_DLL_LIBRARYDLL_API LPSTR CString_Replace(LPSTR,LPCTSTR,LPCTSTR);#ifdef __cplusplus}#endif
      عرض الكل


      PHP كود المصدر

      1. le="color: #000000"><?php __cplusplus

      عبارة عن macro يدلك على أن اللغة التي يتم الإتصال منها بالمكتبة
      البرمجية هي لغة السي بلس
      msdn.microsoft.com/en-us/library/ys435b3s(VS.80).aspx

      PHP كود المصدر

      1. le="color: #000000"><?php extern "C"

      كلمة محجوزة أو أساسية أو مفتاحية تسمح بلإتصال بالوظائف function
      عبر وصلات الإرتباط الحيوي و عن طريق تطبيقات مصممة على لغات السي بلس
      msdn.microsoft.com/en-us/library/0603949d(VS.80).aspx
      و بذالك ستعمل المكتبة على جميع اللغات البرمجية بما فيها السي بلس

      طبعا هناك قوس مفتوح يجب إغلاقة بالقوس المعاكس كتالي

      PHP كود المصدر

      1. le="color: #000000"><?php #ifdef __cplusplus}#endif


      توضيح لهذه العملية كاملة أولا هذه العملية يتم تنفيذها على
      ما يسمى Declaration الوظائف وهذا هووه Declaration
      الوظيفة الأولى بالكود التالي

      PHP كود المصدر

      1. le="color: #000000"><?php int AfxMsBox(LPCTSTR);


      نظيف عليه أولا في حالة الإتصال من تطبيقات مصممة
      على لغة السي بلس الكلمة الLحجوزة

      PHP كود المصدر

      1. le="color: #000000"><?php extern "C"


      ثم من بعد نضيف المتغير الذي عوضنا عنه بإحدى الكلمات المحجوزة التالية

      PHP كود المصدر

      1. le="color: #000000"><?php __declspec(dllexport)

      و

      PHP كود المصدر

      1. le="color: #000000"><?php __declspec(dllimport)


      و هذا هووه المتغير
      MFC_DLL_LIBRARYDLL_API

      و طبعا ما يحدد أي واحدة من بين هذه الكلمات المحجوزة هووه نوعية
      الإتصال الصادر من التطبيق و الذي يقوم بإجراء الإتصال بالمكتبة
      و ستكون النتائج حسب الإحتمالات التالية

      PHP كود المصدر

      1. le="color: #000000"><?php _declspec(dllexport) int AfxMsBox(LPCTSTR);

      أو

      PHP كود المصدر

      1. le="color: #000000"><?php __declspec(dllimport) int AfxMsBox(LPCTSTR);

      أو

      PHP كود المصدر

      1. le="color: #000000"><?php extern "C" __declspec(dllexport) int AfxMsBox(LPCTSTR);

      أو

      PHP كود المصدر

      1. le="color: #000000"><?php extern "C" __declspec(dllimport) int AfxMsBox(LPCTSTR);

      ومن بعد نقوم بعمل الوظائف و ما تحتوي من عمليات منطقية


      - كيفية الإتصال بالمكتبة البرمجية عن طريق تطبيق مصمم على لغة الـ C++ 6

      هذه هي الوظيفة الموجودة على مكتبة الإرتباط الحيوي و التي سنقوم
      بلإتصال بها عن طريق برنامج مصمم على لغة C++6

      PHP كود المصدر

      1. le="color: #000000"><?php int CString_Find(int nStart ,LPSTR FSTR ,LPSTR FSUBSTR){return CString(FSTR).Find(FSUBSTR,nStart);}


      - الإتصال بالمكتبة البرمجية

      PHP كود المصدر

      1. le="color: #000000"><?php HMODULE HMO = LoadLibrary(_T("MFC_DLL_LIBRARY.dll"));

      / أولا أمر تحميل أو رفع المكتبة البرمجية

      PHP كود المصدر

      1. le="color: #000000"><?php typedef int (*parameters) (int,LPSTR,LPSTR);

      / ثانيا نقوم بعمل struct يطابق نوعية متغيرات الوظيفة و ترتيبها

      PHP كود المصدر

      1. le="color: #000000"><?php parameters Proc = (parameters) GetProcAddress(HMO,_T("CString_Find"));

      msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx
      /ثالثا نقوم باستجلاب عنوان الوظيفة الموجودة على المكتبة البرمجية و التي تظهر باسم
      /CString_Find

      PHP كود المصدر

      1. le="color: #000000"><?php Proc( nStart ,FSTR,FSUBSTR);


      /من بعد نقوم باتصال عادي بالوظيفة

      توضيح أكثر لعملية الإتصال

      PHP كود المصدر

      1. le="color: #000000"><?php int CString_Find(int nStart ,LPSTR FSTR ,LPSTR FSUBSTR){return CString(FSTR).Find(FSUBSTR,nStart);}


      أولا توضيح لما يسمى الـ struct

      PHP كود المصدر

      1. le="color: #000000"><?php typedef int (*parameters) (int,LPSTR,LPSTR);

      / ثانيا نقوم بعمل struct يطابق نوعية متغيرات الوظيفة و ترتيبها

      طبعا الوظيفة تحتوي على متغير تحدد نوعيته نوعية بيانات النتائج التي سترجع من بعد الإتصال
      بالوظيفة و إتمام العمليات المنطقية بها و ههوه بنفس نوع المتغير الذي يتم إرجاعه عن طريق الأمر
      return و و بهذه الوظيفة هووه بنوع int و نلاحضه في هذا الجزء من الـ struct
      typedef int

      *parameters
      هووه متغير يحمل قيمة struct كاملة على شكل ما يسمى pointer

      PHP كود المصدر

      1. le="color: #000000"><?php (int,LPSTR,LPSTR);

      أما هذا الجزء فهووه يمثل نوعية متغيرات الوظيفة بنفس
      الترتيب الموجودة عليه بالوظيفة نفسها

      PHP كود المصدر

      1. le="color: #000000"><?php parameters Proc = (parameters) GetProcAddress(HMO,_T("CString_Find"));

      نقوم في هذه العملية عن طريق الأمر GetProcAddress
      باستدعاء عنوان الوظيفة من مكتبة الإرتباط الحيوي و جعل هذا العنوان
      يتماثل مع حالة المتغير parameters الذي قمنا بعمله حسب تنظيم ونوعية
      متغيرات الوظيفة وههووه نيجة الـ struct

      PHP كود المصدر

      1. le="color: #000000"><?php Proc( nStart ,FSTR,FSUBSTR);

      وفي هذا الجزء نحن نتصل بالوظيفة

      صورة تطبيق الإتصال بالمكتبة البرمجية


      الملفات الرائيسية لمشروع عمل مكتبة إرتباط حيوي و أيضا الملفات الرائيسية
      لمشروع تطبيق يقوم بلإتصال بالمكتبة البرمجية مع المكتبة و التطبيق جاهزان
      من المرفقات


      المشروعان كاملان بكافة الملفات من هذا الرابط
      file-upload.eu/download-1520790/MyProjects.zip.html

      تم تحرير الموضوع 1 مرة, آخر مرة بواسطة ناقوس الخطر ().