سؤال

لقد كتبت بعض التعليمات البرمجية التي تستخدم مكتبة مصدر مفتوحة للقيام ببعض الرفع الثقيل. تم تنفيذ هذا العمل في Linux، مع اختبارات الوحدة و Cmake للمساعدة في تشغيله إلى Windows. هناك شرط يجب تشغيله على كل من المنصات.

أحب Linux وأنا أحب Cmake وأنا أحب ذلك يمكنني الحصول على ملفات Visual Studios التي تم إنشاؤها تلقائيا. كما هو الحال الآن، في Windows كل شيء سوف يترجم وسوف يربط وسيقوم بإنشاء الملفات التنفيذية الاختبار.

ومع ذلك، للوصول إلى هذه النقطة اضطررت إلى القتال مع النوافذ لعدة أيام، وتعلم كل شيء عن ملفات البيان والحزم القابلة لإعادة التوزيع.

بقدر ما يذهب فهمي:

مع vs 2005، أنشأت Microsoft جنبا إلى جنب DLLs. الدافع لهذا هو أنه من قبل، ستقوم تطبيقات متعددة بتثبيت إصدارات مختلفة من DLL نفس DLL، مما تسبب في تعطل تطبيقات مثبتة مسبقا وتثبيتها مسبقا (IE "DLL HELL"). قم بإصلاح DLLs Side بواسطة DLL من الجانبين، حيث يوجد الآن "ملف واضح" إلحاق كل تطبيق قابل للتنفيذ / DLL الذي يحدد الإصدار الذي يجب تنفيذه.

هذا هو كل شيء حسن وجيد. يجب أن لا تعطل التطبيقات في غموض. ومع ذلك...

يبدو أن Microsoft تحرير مجموعة جديدة من DLL النظام مع كل إصدار من Visual Studios. أيضا، كما ذكرت سابقا، أنا مطور يحاول ربط مكتبة طرف ثالث. في كثير من الأحيان، تأتي هذه الأشياء موزعة ك "DLL المعتمدة". الآن، ما يحدث عندما يرتبط DLL DLL مسبقا مع إصدار واحد من Visual Studios بتطبيق باستخدام إصدار آخر من Visual Studios؟

من ما قرأته على الإنترنت، يحدث أشياء سيئة. لحسن الحظ، لم أحصل على ذلك بعيدا - ظللت في مشكلة "msvcr80.dll غير موجودة عند تشغيل الملف القابل للتنفيذ، وبالتالي بدأت خيالي في مشكلة البيان بأكملها.

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

هل هذا صحيح صحيح؟ هل افتقد شيئا؟

علاوة على ذلك، إذا كان هذا هو الحال، فلن أتمكن من المساعدة ولكن أعتقد أن Microsoft فعلت هذا عن قصد لأسباب نكسية.

لا يقتصر الأمر فحسب، مما يكسر كل الثنائيات التي تجعل من الصعب استخدامها دون داع استخدام الثنائيات التي تعمل بشكل غير ضروري، إذا حدثت العمل في شركة برمجية تستخدم مكتبات ملكية الطرف الثالث، فكلما كانت تقوم بالترقية إلى أحدث إصدار من Visual Studios - يجب على شركتك الآن تفعل الشيء نفسه أو الرمز لن يتم تشغيله.

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

أخيرا، يلخص: هل من الممكن استخدام الثنائيات المعادلة مع هذا المخطط الواضح الجديد؟ إذا كان، ما هو خطأي؟ إذا لم يكن الأمر كذلك، فهل مايكروسوفت بصراحة أعتقد أن هذا يجعل تطوير التطبيق أسهل؟

تحديث - سؤال أكثر عرضة: كيف يتجنب نظام Linux استخدام ملفات البيان؟

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

المحلول

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

هذا هو نفسه على جميع المنصات. انها ليست شيء اخترع مايكروسوفت.

قد تتجول في مشكلة "وقت التشغيل الوحيد فقط" من خلال إدراك حيث قد تعود الجري إلى الوراء. هذا في الغالب في الحالات التي تخصم فيها الذاكرة في وحدة واحدة، وتحريرها في مكان آخر.

a.dll
    dllexport void* createBla() { return malloc( 100 ); }

b.dll
    void consumeBla() { void* p = createBla(); free( p ); }

عندما ترتبط A.dll و B.dll بأوقات جديدة مختلفة، فإن هذا التعطل، لأن وظائف وقت التشغيل تنفذ كومة كومة خاصة بها.

يمكنك بسهولة تجنب هذه المشكلة من خلال توفير وظيفة DestroyBla التي يجب استدعاؤها لتحرير الذاكرة.

هناك العديد من النقاط التي قد تواجهها مشاكل في وقت التشغيل، ولكن يمكن تجنب معظمها عن طريق التفاف هذه البنيات.

كمرجع :

  • لا تخصص / ذاكرة مجانية / كائنات مجانية عبر حدود الوحدة النمطية
  • لا تستخدم كائنات معقدة في واجهة DLL الخاصة بك. (على سبيل المثال STD :: سلسلة، ...)
  • لا تستخدم آليات C ++ تفصيلا عبر حدود DLL. (TypeInfo، C ++ استثناءات، ...)
  • ...

ولكن هذه ليست مشكلة مع البيان.

يحتوي البيان على معلومات الإصدار من وقت التشغيل المستخدمة من قبل الوحدة النمطية ويتم تضمينها في الرابط الثنائي (EXE / DLL). عند تحميل التطبيق ويجب حل تبعياتها، ينظر المحمل إلى معلومات البيان المضمنة في ملف EXE ويستخدم إصداره وفقا لإصدار DLLs Runtime من مجلد Winsxs. لا يمكنك فقط نسخ وقت التشغيل أو الوحدات النمطية الأخرى إلى مجلد Winsxs. عليك تثبيت وقت التشغيل المعروض من قبل Microsoft. هناك حزم MSI المقدمة من Microsoft والتي يمكن تنفيذها عند تثبيت البرنامج الخاص بك على جهاز اختبار / نهاية.

لذا قم بتثبيت وقت التشغيل الخاص بك قبل استخدام التطبيق الخاص بك، ولن تحصل على خطأ "التبعية المفقودة".


(تم التحديث إلى "كيفية تجنب Linux استخدام سؤال" ملفات البيان ")

ما هو ملف البيان؟

تم تقديم ملفات البيان لوضع معلومات الغموض بجوار مكتبة الارتباط القابلة للتنفيذ / الديناميكي القابل للتنفيذ أو المدمجة مباشرة في هذا الملف.

يتم ذلك عن طريق تحديد الإصدار المحدد من DLLS الذي سيتم تحميله عند بدء تشغيل التبعيات التطبيق / تحميل.

(هناك العديد من الأشياء الأخرى التي يمكنك القيام بها مع ملفات البيان، على سبيل المثال، قد يتم وضع بعض بيانات التعريف هنا)

لماذا يتم ذلك؟

الإصدار ليس جزءا من اسم DLL بسبب الأسباب التاريخية. لذلك يتم تسمية "comctl32.dll" بهذه الطريقة في جميع إصدارات ذلك. (لذلك يختلف COMCTL32 تحت WIN2K عن واحد في XP أو Vista). لتحديد الإصدار الذي تريده حقا (واختباره)، يمكنك وضع معلومات الإصدار في ملف "Appname.exe.manifest" (أو تضمين هذا الملف / المعلومات).

لماذا فعلت بهذه الطريقة؟

تثبيت العديد من البرامج DLLs الخاصة بهم في دليل System32 على Systemrootdir. تم القيام بذلك للسماح بنشر Bugfixes إلى المكتبات المشتركة بسهولة لجميع التطبيقات المعتمدة. وفي أيام الذاكرة المحدودة، خفضت المكتبات المشتركة بصمة الذاكرة عندما تستخدم العديد من التطبيقات نفس المكتبات.

تم إساءة استخدام هذا المفهوم من قبل العديد من المبرمجين، عند تثبيت جميع DLLs في هذا الدليل؛ في بعض الأحيان الكتابة فوق الإصدارات الأحدث للمكتبات المشتركة مع كبار السن. في بعض الأحيان تغيرت المكتبات بصمت في سلوكها، بحيث تعطلت التطبيقات المعتمدة.

يؤدي ذلك إلى نهج "توزيع جميع DLLs في دليل التطبيق".

لماذا كان هذا سيئا؟

عندما ظهرت الأخطاء، يجب تحديث جميع DLLs المنتشرة في عدة أدلة. (gdiplus.dll) في حالات أخرى لم يكن هذا ممكنا (مكونات Windows)

نهج البيان

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

لماذا لا يوجد لينكس هذا الميكانيكي؟

لدي العديد من التخمينات. (هذا هو مجرد تخمين فقط ...)

  • معظم الأشياء مفتوحة المصدر، لذلك يعد إعادة ترجمة Bugfix غير مشكلة بالنسبة للجمهور المستهدف
  • نظرا لعدم وجود "وقت التشغيل" فقط (وقت تشغيل دول مجلس التعاون الخليجي)، فإن المشكلة في حدود مشاركة / مكتبة وقت التشغيل لا تحدث في كثير من الأحيان
  • تستخدم العديد من المكونات C على مستوى الواجهة، حيث لا تحدث هذه المشكلات فقط إذا قمت بذلك بشكل صحيح
  • إصدار المكتبات في معظم الحالات المضمنة باسم ملفه.
  • معظم التطبيقات مرتبطة قانونيا بمكتباتها، لذلك قد يحدث DLL-Hell.
  • تم الاحتفاظ وقت تشغيل دول مجلس التعاون الخليجي للغاية بحيث لا يمكن أن تحدث هذه المشاكل.

نصائح أخرى

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

يستخدم DLL الطرف الثالث std حاويات، مثل vector, ، إلخ. هل يمكن أن يكون لديك مشاكل حيث قد يكون تخطيط الكائنات مختلفا تماما.

من الممكن الحصول على أشياء للعمل، ولكن هناك بعض القيود. لقد واجهت كل من المشكلات التي أدرجتها أعلاه.

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

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

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

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

...كما أفهمها. :)

(خط العمل الخاص بي ليس في Windows على الرغم من أننا نقوم بالمعركة مع DLLs على Windows من منظور المستخدم من وقت لآخر، ومع ذلك، يجب علينا استخدام إصدارات محددة من التحويل البرمجي والحصول على إصدارات من برنامج الحزب الثالث الذي تم بناؤه جميعا مع نفس المترجم. لحسن الحظ يميل جميع البائعين إلى البقاء إلى حد ما، لأنهم كانوا يفعلون هذا النوع من الدعم لسنوات عديدة.)

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