ما هي الوظائف التي يؤديها _WinMainCrtStartup؟
-
21-09-2019 - |
سؤال
هذا جزء من سلسلة من أسئلة اثنين على الأقل ذات الصلة ، ولكن متميزة. آمل أن أفعل الشيء الصحيح من خلال سؤالهم بشكل منفصل.
أحاول تشغيل تطبيق C ++ 2008 الخاص بي بدون مكتبة وقت التشغيل C. إنه تطبيق واجهة المستخدم الرسومية Win32 بدون MFC أو غيرها من الأشياء الفاخرة ، فقط Windows API.
لذلك قمت بتعيين خصائص المشروع -> التكوين -> C/C ++ -> Advanced -> حذف أسماء المكتبات الافتراضية إلى YES (علامة التحويل البرمجي /Zl
) وإعادة بنائها.
ثم يشتكي الرابط من خارجي لم يحل _WinMainCRTStartup
. عادلة بما فيه الكفاية ، يمكنني أن أخبر الرابط باستخدام نقطة دخول مختلفة ، على سبيل المثال MyStartup
. من ما أجمعه حول الويب ، _WinMainCRTStartup
هل بعض الأشياء التهيئة ، وربما أريد MyStartup
للقيام بمجموعة فرعية من ذلك.
لذلك سؤالي هو: ما هي الوظائف _WinMainCRTStartup
أداء ، وأي من هؤلاء يمكنني حذفه إذا لم أستخدم CRT؟
إذا كنت على دراية بهذه الأشياء ، فيرجى إلقاء نظرة على سؤالي الآخر جدا. شكرًا!
جانبا: لماذا أريد أن أفعل هذا في المقام الأول؟
- لا يستخدم تطبيقي بشكل صريح أي وظائف CRT.
- أحب التطبيقات العجاف والمتوسطة.
- سوف يعلمني شيء جديد.
المحلول
تقوم نقطة دخول 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