لماذا تفشل .LIB المترجمة في VS2003 في الارتباط برمز محمول مع VS2008؟

StackOverflow https://stackoverflow.com/questions/1272139

سؤال

كان لدينا تجربة مثيرة للاهتمام في محاولة ربط مجموعة من التعليمات البرمجية المترجمة باستخدام Visual Studio Express 2008 باستخدام .LIB مترجمة مع Visual Studio 2003. الكل في C ++. أن تكون دقيقة، كان systemc. 2.2.0 Kernel الذي تم تجميعه في VS2003 في .LIB، ونموذج نظام تم تجميعه في VS2008.

عند الارتباط، حافظنا على الحصول على الخطأ الذي لم يتم العثور على عدد قليل من الرموز من ملف systemc.lib (أي، مجمعة في VS2003) أثناء الارتباط. الخطأ الذي نحصل عليه كان هذا (في عدد قليل من المتغيرات):

SystemC.lib(sc_port.obj) : error LNK2001: unresolved external symbol "public: vo
id __thiscall std::_String_base::_Xran(void)const " (?_Xran@_String_base@std@@QB
EXXZ)

حفر من مختلف الخيوط، اتضح أن وظيفة .LIB المتوقع أن يجد هذا:

Undecoration of :- "?_Xran@_String_base@std@@QBEXXZ"
is :- "public: void __thiscall std::_String_base::_Xran(void)const "

في حين أن ملف المكتبة الذي كان يعمل VS2008 كان يحاول الارتباط به (libcpmt.lib) استخدم اتفاقية استدعاء مختلفة:

Undecoration of :- "?_Xran@_String_base@std@@SAXXZ"
is :- "public: static void __cdecl std::_String_base::_Xran(void)"

حاولت معرفة سبب حدوث هذا عدم التوافق، ولكن في النهاية استسلمت، أو إعادة ترجمة نفس مشروع Visual Studio بالضبط في VS2008، واستخدامه هذا systemc.lib بدلا من واحد من VS2003. الآن، عملت الأمور تماما.

وبالتالي فإن السؤال الأساسي هنا هو: ما الذي تغير من VS2003 إلى VS2008 من شأنه أن يسبب بعض الوظائف لتغيير اتفاقياتهم المتصلين؟ وهناك بعض العلم السحري لإعطاء المرتبطة في VS2008 لاستخدام بعض المكتبة الأخرى حيث تحتوي الوظائف على نفس اتفاقية الاتصال كما في ترجمة VS2003؟

تحديث، ملخص الإجابات حتى الآن: من المحتمل جدا أن تغير Microsoft C ++ (وليس C، فقط C ++) ABI من إصدار رئيسي واحد من Visual Studio إلى التالي. يمكن أن يكون هناك أيضا تغييرات أخرى في المكتبات التي تسبب عدم التوافق. أفضل نصيحة هي إعادة ترجمة .LIB لكل إصدار مقابل في الأساس، قم فقط بتشغيله في المصدر للمستخدمين ولديه تجميعه محليا باستخدام أي إصدار من VS الذي حدث مثبت عليه.

تم اكتشاف القضية الأساسية باستخدام المشورة في:

لاحظ أن هذه الأسئلة لم ترد على هذه المشكلة:

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

المحلول

لا يوجد معيار ل C ++ ABI. مما يعني أن جميع مترجم C ++ يمكنه التعامل مع ABI مختلفة من واحد إلى آخر، ويشمل ذلك إصدارا مختلفا من التحويل البرمجي نفسه. يمكن أن يكون لديك نفس المشكلة مع 2 بيان كبير مختلف من دول مجلس التعاون الخليجي. قد يحدث هذا التعديل عندما يجدون طريقة لتحسين خطوة الارتباط.

لكن أبي ينطوي على الكثير من ذلك. على سبيل المثال، يتم تخزين طريقة Vtable وتتعامل مع غطاء محرك السيارة من خلال التعليمات البرمجية التي تم إنشاؤها بواسطة برنامج التحويل البرمجي. إذا تغيرت، فإن الكائنات الخاصة بك وعلى الكود الخاص بك ولدت في عام 2008 لن تكون متوافقة مع المكتبة تتوقع الطريقة التي يتم بها في عام 2003.

في هذه المرحلة، يمكنك أن تفهم لماذا يتم شحن مكتبات C ++ مع شفرة المصدر الخاصة بها أو يتم شحنها كثير بنية ومجمعات مترجم مختلفة.

عادة عند كتابة مكتبة، من أجل تجنب مثل هذه المشكلات، تقوم بتطويرها في Langage C، وليس C ++. نظرا لأن C يأتي مع ABI موحدا، فأنت قادرا على تجميعه بمبرمج واحد ثم ربط هذه المكتبة بأي مبرر C Wich باحترام قياسي C ABI. على سبيل المثال، يتم تنفيذ سلسلة الأحرف هي المعيار وربما لن تتحرك أبدا (سلسلة إنهاء سيئة السمعة). في حين أن التغييرات STD :: تغيير السلسلة من إصدار كبير في دول مجلس التعاون الخليجي إلى الآخر (فقط إلقاء نظرة على الفئة الأساسية من / USR / تشمل / C ++ / XX / BITS / Basic_String الملفات)

نصائح أخرى

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

عادة ما يمكن تقليلها عن طريق ربط ديناميكيا مع CRT، كان لدي نجاح إعادة استخدام المكتبات VS2003 في VS2005 ولكنها مزعجة، من الأفضل إعادة ترجمة كل شيء. في بعض الأحيان يمكنك الابتعاد باستخدام / nodefaultlib. علم المترجم لتجنب ربط مكتبة CRT معينة تسبب مشاكل.

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