السلام عليكم ورحمة الله ,,,
في البداية قررت كتابة الموضوع بعد أن شاهدت برنامج غريب ؟
هذا البرنامج عبارة عن باحث للملفات فقط وهو موزع على النت بشكل نهائي أي نسخة التوزيع النهائي
ومشكلة البرنامج هي في الحجم ؟ فحجم البرنامج تقريبا 1.2 ميجا بايت وهو في الأصل لا يتعدى 680 كيلوبايت
والمشكلة الثانية في أن البرنامج يقوم بتحميل مكاتب ربط لا يستخدمها أصلا ؟ وأخطاء أخرى
المهم أني حاولت إكتشاف لغز هذا البرنامج .. ليظهر في النهاية أنة خطأ كبير في خصائص ترجمة البرنامج!
وأردت طرح هذا الموضوع لكي لا يقع في هذا الخطأ أحد أعضاء المنتدى ؟
أولاً : خيارات الرابط وخصائصة
شغل برنامج الفيجول سي6 وإختر مشروع Win32 Application ثم قم بتسمية البرنامج Mypro مثلا وإضغط Ok
ستظهر لك نافذة إختر منها الخيار الأول مشروع فارغ An empty project
ستلاحظ أن المترجم فتح لك مشروع فارغ ... بعد ذلك إختر من قائمة مترجم الفيجول سي الأمر File ثم New
ستظهر لك نافذة إختر منها ملف مصدري بهذا الشكل

ثم إضغط OK ليتم إضافة الملف إلى المشروع
إفتح الملف المصدري :
سنقوم بكتابة برنامج بسيط عبارة عن مسج بمعنى أننا سنستخدم الدالة الرئيسية لبرامج وندوز وهي WinMain
ودالة إظهار المسج وهي MessageBox... إكتب الكود التالي
#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MessageBox (NULL,"Win32",NULL,MB_OK);
return 0;
}ثم ترجم البرنامج .. من قائمة Build ثم Build Mypro.exe
الآن كيف ترجمت البرنامج ؟ هل تعلم أنك إستخدمت أكثر من خيار للرابط .. تابع
في أول سطر كتبت #include <windows.h> وهو ملف الهدر أو الترويسة لدالة المسج
وبعدها قام المترجم بشكل إفتراضي بتحديد تعريف المكتبة وهي user32.lib
ثم قام الرابط بربط البرنامج مع المكتبة user32.dll
قد تكون الطريقة غير واضحة لأننا إستخدمنا دالة لمكتبة إفتراضية
أرجع للكود وأكتب هذة الدالة PlaySound وهي دالة لتشغيل ملف صوتي
ليصبح شكل البرنامج بهذة الطريقة
#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
PlaySound ("my.wav",NULL,0x8);
return 0;
}إذا ترجمت البرنامج سيظهر أكثر من خطأ لأنك لم تعرف ملف الترويسة للدالة PlaySound
إبحث عن الدالة ستجدها في الملف mmsystem.h .. عرف هذا الملف في بداية البرنامج بإستخدام #include
ثم ترجم البرنامج .. سيظهر خطأ لأنك لم تقم بتعريف المكتبة التي تحتوي الدالة
بمعنى أن الدالة موجودة في المكتبة winmm.dll وتعريفها للرابط يكون winmm.lib
أسهل طريقة لتعريف المكتبة ... من قائمة Project إختر Settings ثم حدد Link
وأكتب تعريف المكتبة بجانب التعاريف الإفتراضية بهذا الشكل

ملاحظة : طبق هذة العملية على كل نسخ البرنامج .. بمعنى النسخة Win32 Debug وWin32 Release
يتم إختيار النسخة في أعلى النافذة عند الخيار Settings For
والآن ترجم البرنامج ... ليظهر لك المترجم إتمام عملية الترجمة بنجاح
إذهب إلى مجلد المشروع في مثالنا X:\mypro ستجد مجلد Debug بداخلة Mypro.exe
هذا هو برنامجنا بعد الترجمة ... ولكنة ليس النسخة النهائية ؟ لاحظ حجم البرنامج 152 كيلوبايت ..معقولة
إرجع لنافذة الفيجول سي وإختر من القائمة Build ثم Set Active Configuration
ستظهر لك نافذة بها خيارين الأول Mypro.exe Release والثاني Mypro.exe Debug
إختر الخيار الأول ثم أعد ترجمة البرنامج وإذهب إلى مجلد البرنامج لتجد المجلد Release وبة الملف exe
حجم البرنامج 24 KB وهو حجم قد يكون معقول
ماذا لو أردت توزيع البرنامج بشكل نهائي ؟
خيارات المترجم وخصائصة :
خيارت المترجم كثيرة تقريبا 74 ... منها مثلا #pragma warning لتحديد مستوى التحذير
ولابد لأي شخص يريد إحتراف اللغة من فهم أغلب هذة التعليمات
وسأشرح في هذا الموضوع أهمها :
توجد ثلاث طرق لتحديد خصائص المترجم وهي:
عن طريق الكود داخل البرنامج + عن طريق الدوس +عن طريق نافذة خصائص البرنامج
إفتح المشروع الخاص بناء ومن قائمة project إختر Settings ثم حدد c\c++

تختار من النافذة أي قسم من أقسام المترجم
ثم تحدد الخصائص وتغيرها .. وأي تغيير في الخصائص العامة سيحدث تغيير في رموز المترجم
بمعنى أنك تستطيع أن تغير إما في الرموز أو الخصائص وكلا الطريقيتن نفس الشيء
الخيار Optimizations وإختصارة O/ :
إما أن يكون Maximize Speed ورمزة O2/
أو Minimize Size ورمزة O1/
O2 معناة ترجمة البرنامج لأسرع تنفيذ والخيار O1 ترجمة البرنامج لأصغر حجم
وأعتقد أنهما نفس الشيء بمعنى أنك تختار إما يكون البرنامج سريع أو صغير ؟؟
أغلب البرامج التجارية تستخدم O2 ولكني قرأت مقال في أحد الكتب أن مايكروسفت تكتب برامجها
تحت الخيار O1 وإذا أردت تقليد مايكروسفت إستخدم هذا الخيار ,, وإلى إستخدم الخيار الثاني
ونفس التغيير بالكود #pragma optimize
الإختيار Warning level :
مستوى الإنذار بمعنى متى تريد من المترجم أن يعتبر الكود على أنة
إنذار لخطأ ... أفضل إختيار هو level1
لتغيير هذا الإختيار بالكود : #pragma warning
الآن أنظر للخيار الأخير : WIN32,NDEBUG,_WINDOWS,_MBCS
معنى الكلمة _MBCS أنك تريد إستخدام الحروف الموسعة وليس ترميز اليونيكود
إذا أردت ترميز اليونيكود غير إلى _UNICODE
هذة أهم النقاط في هذة النافذة
إرجع إلى الصورة ومن قائمة أقسام وخصائص المترجم إختر القسم Code Generation
لاحظ خصائص على يمين النافذة Use run-time library ينقسم إلى 6 ويالي يهمنا 3 وهم
Single-Threaded
MultitThreaded
MultitThreaded DLL
هذة 3 الإختيارات خاصة بالأكواد التي ستضاف إلى البرنامج
مثل تعليمات المايكرو strcpy .. بمعنى أي كود تكتبة في البرنامج غير دوال API
بإختصار توجد 3 مكاتب تشغيل قياسية في لغة السي وهي LIBC.LIB -LIBCMT.LIB -MSVCRT.LIB
إذا إخترت الإختيار الأول وهو Single-Threaded سيتم ربط البرنامج مع المكتبة LIBC.LIB
وخصائص هذة المكتبة أن الأكواد ستضاف إلى نفس ثريد البرنامج بمعنى أنها ستنفذ في وسط البرنامج
وأي خطأ أو تأخر في التنفيذ سيحسب من وقت البرنامج !
الإختيار الثاني MultitThreaded المكتبة LIBCMT.LIB
خصائصها أن أي كود مضاف من المترجم سيتم تنفيذة خارج ثريد البرنامج ولن يأثر على خط سير
البرنامج ووقتة ... وأعتقد أنة أفضل خيار في بعض الحالات ؟
الإختيار الثالث MultitThreaded DLL المكتبة MSVCRT.LIB
لن يكتب المترجم أي كود إضافي في البرنامج ولكن سيتم ربط برنامجك مع مكتبة ربط الخاصة
بلغة السي++ وهي MSVCRT.DLL وأكيد هذة المكتبة متوفرة في أغلب الأجهزة
والسؤال بعد هذة المقدمة ماذا أختار ؟؟
دائما الإختيار الأول هو أضمن خيار 100%100 إذا لم تستخدم المايكرو وأوامر المترجم بكثرة
الإختيار الثاني أكيد مضمون وتقوم بإختيارة إذا إستخدمت أوامر المترجم بشكل كبير ولا تريدها أن تقلل سرعة البرنامج
الإختيار الثالث إذا أردت تصغير حجم برنامجك بشكل كبير ولكن مع ضمان وجود المكتبة MSVCRT.DLL
أما عن البرامج التجارية وبرامج مايكروسف فهذا الإختيار يكون على حسب حجم البرنامج
وهذا مالاحظتة !
---------
بالتأكيد لم ننهي الموضوع ..... ومازال الموضوع في بدايتة :)
وبالتوفيق

