سؤال

عند تطوير ونشر تطبيقات Windows الأصلية، غالبا ما أحتاج إلى تثبيت وقت التشغيل قبل أن أكون قادرا على تشغيل مكتبة ثنائي، أو ترتبط بشكل ثابت مع My Binary. على سبيل المثال، بعد إنشاء مشروع "وحدة التحكم Win32" مع Visual Studio 2008، حاول تشغيل البرنامج على نتائج صورة Windows 7 جديدة في:

فشل التطبيق في البدء لأن تكوينها الجانبي غير صحيح. يرجى الاطلاع على سجل أحداث التطبيق أو استخدم أداة SXSTRACE.EXE سطر الأوامر لمزيد من التفاصيل.

القضايا مثل هذا واحد قد نشأ في المشاركات الأخرى على stackoverflow.

كيف يطور أحد التطبيقات لا تتطلب إجراء تشغيل غير موجود بالفعل على نظام التشغيل المستهدف (أي لا تحتاج إلى تثبيت حزم إعادة التوزيع أو التجميعات الجانبية الخاصة / المشتركة)؟ كيف يتجنب المرء استخدام MSVC [MPR] 90.DLL واستخدم فقط Windows API في Windows System32 *. {DLL، SYS}؟

أنا أفكر على طول خطوط التعليمات البرمجة التي تخرج من Demoscene، لكن هذا غير متوفر.

هل كانت مفيدة؟

المحلول

وقد استجاب آخرون بالفعل فيما يتعلق بربط CRT بشكل ثابت. إذا كنت تريد أيضا ثنائيا صغيرا في نفس الوقت، فمن المفترض أن أفضل رهان يتفوق تماما على CRT بالكامل، واستخدام وظائف API Win32 فقط قدر الإمكان. ما زلت تحصل على بعض كود CRT، والأبرز المرتبط ببدء التشغيل (أي الذي يستدعي main) وإغلاق (atexit التعامل مع الخ)، ولكن دون رابط لن يربط وظائف CRT التي لا تستخدمها.

يمكنك تجنب ربط CRT تماما باستخدام /Zl رمز التحويل البرمجي. هذا يعني ذاك main لن تعمل، ومع ذلك - ستحتاج إلى تحديد WinMain (الاسم لا يهم، ولكن يجب أن يتطابق التوقيع، ويجب أن يكون __stdcall)، وسيتعين عليك تحديد اسم الخاص بك WinMain- مثل وظيفة نقطة الدخول عبر رابط /entry: مفتاح كهربائي. هذا سيوفر لك ~ 30 كيلو بايت من رمز CRT (تم اختباره على .cpp مع فارغة main).

إذا ذهبت إلى الطريق الأخير، فقد تضطر أيضا إلى التعامل مع إصدار جوهري جوهري. هناك بعض الوظائف التي يتم تعريفها بشكل اسمي بواسطة CRT (وأعلن في رؤوسها)، ولكنها تعامل بشكل خاص من قبل المترجم، بحيث تدرج تعليمات التجميع الأمثل عند نقطة المكالمة حيثما أمكن - أمثلة memset, strlen, ، قطعة جيدة من الوظائف في <math.h>; ؛ يمكن العثور على قائمة كاملة هنا. وبعد نظرا لعدم الحصول على CRT، إذا كنت بحاجة إلى هذه الوظائف، أو يمكن تجنبها ولكنها تفضل الجوهرية بسبب تحسين الأداء (من الصعب القيام بذلك بشكل أفضل من memset, ، على سبيل المثال)، ثم عليك أن تعلن عن نفسك، واستخدام #pragma intrinsic. وبعد على سبيل المثال:

// Contains macros and typedef only, so safe to include without CRT.
// We need it here for size_t.
#include <stddef.h> 

extern "C"
{
    int abs(int);
    void* memset(void*, int, size_t); 
}

#pragma intrinsic(abs, memset)

int __stdcall main(void*, void*, char*, int)
{
    char tmp[10];
    memset(tmp, abs(-123), 10);
    return 0;
}

ما سبق يمكن تجميعها مع:

cl /c /Zl foo.cpp
link /entry:main foo.obj

نصائح أخرى

ربط CRT بشكل ثابت عبر /MT قم بالتبديل (ومثل MFC، إذا كنت تستخدمه).

حدود ربط ثابتة ما يمكنك القيام به مع DLLs إلى حد ما، ولكن بالنسبة لتنفيذ التنفيذ البسيط، فإنه يعمل مثل سحر. (وإذا كنت تقوم بشحن DLLS، يمكنك دائما شحن التجميعات الخاصة على أي حال.)

استخدام CRT ثابت. هذا لا يخلق تبعية على MSVC * .dll. يرتبط CRT مباشرة في البرنامج الخاص بك. هذا لا يخلق التبعيات، ولكنه يزيد من حجم قابل التنفيذ الخاص بك.

مزيد من المعلومات حول خيارات CRT المختلفة هنا.

ربط ثابتة وقت التشغيل. MS Visual C ++ لديه خيار / MT لهذا (الافتراضي / MD)

أعتقد أن طريقة واحدة للقيام بذلك لا تستخدم فقط Visual Studio وبدلا من ذلك الاعتماد على أدوات SDK سطر الأوامر. (يمكنك معرفة كيفية تكوين vs للقيام بما تريد، ولكن يبدو ذلك أصعبا.) على سبيل المثال:

cl /c app.cpp
link app.obj ws2_32.lib
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top