سؤال

هذا جزء من سلسلة من أسئلة اثنين على الأقل ذات الصلة ، ولكن متميزة. آمل أن أفعل الشيء الصحيح من خلال سؤالهم بشكل منفصل.

أحاول تشغيل تطبيق C ++ 2008 الخاص بي بدون مكتبة وقت التشغيل C. إنه تطبيق واجهة المستخدم الرسومية Win32 بدون MFC أو غيرها من الأشياء الفاخرة ، فقط Windows API.

لذلك قمت بتعيين خصائص المشروع -> التكوين -> C/C ++ -> Advanced -> حذف أسماء المكتبات الافتراضية إلى YES (علامة التحويل البرمجي /Zl) وإعادة بنائها.

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

لذلك سؤالي هو: ما هي الوظائف _WinMainCRTStartup أداء ، وأي من هؤلاء يمكنني حذفه إذا لم أستخدم CRT؟

إذا كنت على دراية بهذه الأشياء ، فيرجى إلقاء نظرة على سؤالي الآخر جدا. شكرًا!

جانبا: لماذا أريد أن أفعل هذا في المقام الأول؟

  1. لا يستخدم تطبيقي بشكل صريح أي وظائف CRT.
  2. أحب التطبيقات العجاف والمتوسطة.
  3. سوف يعلمني شيء جديد.
هل كانت مفيدة؟

المحلول

تقوم نقطة دخول CRT بما يلي (هذه القائمة غير كاملة):

  • تهيئة الحالة العالمية التي تحتاجها CRT. إذا لم يتم ذلك ، لا يمكنك استخدام أي وظائف أو حالة توفرها CRT.
  • تهيئة بعض الحالة العالمية التي يستخدمها المترجم. الشيكات وقت التشغيل مثل ملف تعريف الارتباط الأمنية المستخدمة من قبل /GS يبرز بالتأكيد هنا. تستطيع الاتصال __security_init_cookie نفسك ، ومع ذلك. قد تحتاج إلى إضافة رمز آخر لفحوصات وقت التشغيل الأخرى.
  • المكالمات المُنشئين على كائنات C ++. إذا كنت تكتب رمز C ++ ، فقد تحتاج إلى محاكاة هذا.
  • يسترجع سطر الأوامر وبدء المعلومات المقدمة من نظام التشغيل ويمرره الرئيسي. بشكل افتراضي ، لا يتم تمرير أي معلمات إلى نقطة دخول البرنامج من قبل نظام التشغيل - فهي جميعها مثبتة من قبل CRT.

يتوفر رمز المصدر CRT مع Visual Studio ويمكنك الانتقال عبر نقطة دخول CRT في مصحح أخطاء ومعرفة ما تفعله بالضبط.

نصائح أخرى

أ حقيقي برنامج Win32 المكتوب في C (وليس C ++) لا يحتاج إلى أي تهيئة على الإطلاق ، حتى تتمكن من بدء مشروعك winmaincrtstartup () بدلاً من وينمين (هينستانس ، ...).

من الممكن أيضًا كتابة برامج وحدة تحكم لتطبيقات Win32 الحقيقية ؛ الاسم الافتراضي لنقطة الدخول هو _maincrtstartup ().

تعطيل جميع ميزات توليد الكود الإضافية مثل تحقيقات المكدس ، وفحص الصفيف وما إلى ذلك. لا يزال تصحيح الأخطاء ممكنًا.

التهيئة

في بعض الأحيان تحتاج إلى الأول Hinstance معامل. بالنسبة لـ Win32 (باستثناء Win32s) ، يتم إصلاحه (Hinstance) 0x400000.

ال NCMDSHOW المعلمة دائما SW_ShowDefault.

إذا لزم الأمر ، استرجع سطر الأوامر مع getCommandline ().

نهاية

عندما يولد البرنامج المواضيع ، على سبيل المثال عن طريق الاتصال getOpenFilename (), ، العودة من winmaincrtstartup () مع إرجاع ستعلق الكلمة الرئيسية البرنامج - الاستخدام ExitProcess () في حين أن.

تحفظات

سوف تواجه مشكلة كبيرة عندما:

  • باستخدام إطارات المكدس (أي المتغيرات المحلية) أكبر من 4 كيلومترات (لكل وظيفة)
  • باستخدام الحساب النقطة العائمة (على سبيل المثال ، تحويل int)
  • باستخدام أعداد صحيحة 64 بت على آلات 32 بت (مضاعفة عمليات التحول)
  • باستخدام C ++ الجديد, حذف, والكائنات الثابتة مع مُنشئين غير صفريين
  • باستخدام وظائف المكتبة القياسية مثل fopen (), printf () بالطبع

استكشاف الاخطاء

هناك مكتبة قياسية C متوفرة على جميع أنظمة Windows (منذ Windows 95) ، msvcrt.dll.

لاستخدامه ، استيراد نقاط الدخول الخاصة بهم ، على سبيل المثال باستخدام بلدي msvcrt-light.lib (Google لذلك). ولكن لا يزال هناك بعض التحذيرات ، خاصة عند استخدام المترجمين الأحدث من MSVC6:

  • لا تزال إطارات المكدس مقصورة على 4 كيلو بايت
  • _ftol_sse أو _ftol2_sse يجب توجيهه إلى _ftol
  • _iob_func يجب توجيهه إلى _iob

يبدو أن تهيئةها تعمل في وقت التحميل. على الأقل ستعمل وظائف الملف على نحو مفيد.

السؤال القديم ، لكن الإجابات إما غير صحيحة أو تركز على مشكلة واحدة محددة.

هناك عدد من ميزات C و C ++ التي لن تتوفر ببساطة على Windows (أو معظم أنظمة التشغيل ، لهذه المسألة) إذا بدأت البرامج بالفعل في Main/WinMain.

خذ هذا المثال البسيط:

class my_class
{
public:
    my_class() { m_val = 5; }
    int my_func(){ return m_val }
private:
    int m_val;
}

my_class g_class;

int main(int argc, char **argv)
{
     return g_class.my_func();
}

لكي يعمل هذا البرنامج كما هو متوقع ، يجب استدعاء مُنشئ my_class قبل الرئيسي. إذا بدأ البرنامج في MAIN بالضبط ، فسيتطلب ذلك اختراقًا للمترجم (ملاحظة: يقوم GCC بذلك في بعض الحالات) بإدراج استدعاء وظيفة في بداية الرئيسية. بدلاً من ذلك ، في معظم الأنظمة ، وفي معظم الحالات ، تقوم دالة مختلفة بإنشاء G_Class ثم تستدعي Main (على Windows ، هذا إما maincrtstartup أو WinMaincrtStartup ؛ على معظم أنظمة أخرى اعتدت عليها هي وظيفة تسمى _start).

هناك أشياء أخرى C ++ وحتى C تتطلب القيام بها قبل أو بعد MAIN للعمل. كيف يتم استخدام stdin و stdout (std :: cin و std :: cout) قابلة للاستخدام بمجرد أن يبدأ الرئيسي؟ كيف يعمل atexit؟

يتطلب المعيار C أن يكون للمكتبة القياسية واجهة برمجة تطبيقات تشبه POSIX ، والتي يجب "تثبيتها" على Windows قبل Main ().

على معظم أنظمة التشغيل ، لا يوجد كومة مقدمة من النظام ؛ يقوم وقت التشغيل C بتنفيذ كومةه الخاصة (وقت تشغيل C Microsoft يلف وظائف كومة kernel32).

حتى الحجج التي تم تمريرها إلى Main و Argc و Argv ، يجب الحصول عليها من النظام بطريقة أو بأخرى.

قد ترغب في إلقاء نظرة على مقالات Matt Pietrick (القديمة) حول تنفيذ وقت تشغيل C الخاص به لتفاصيل حول كيفية عمل هذا مع Windows + MSVC (ملاحظة: Mingw و Cygwin تنفذ أشياء محددة بشكل مختلف ، ولكن في الواقع تعود إلى MSVCRT لمعظم الأشياء ):http://msdn.microsoft.com/en-us/library/bb985746.aspx

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top