سؤال

لدي الموقف التالي: أحتاج إلى إنشاء عنصر واجهة مستقلة في مكتبة ثابتة مستقلة ، والتي سيتم ربطها بعد ذلك بالتطبيق النهائي (Visual C ++ 9.0 ، QT 4.5). تحتوي مكتبة القطعة الثابتة هذه على بعض الموارد (الرموز) ، وتتألف من عدة ملفات .CPP (تحتوي كل منها على عنصر واجهة مستقلة). على حد علمي ، يجب أن أقوم بتهيئة نظام موارد QT ، إذا كنت أستخدمها (الموارد) في مكتبة ثابتة ، مع استدعاء إلى "Q_INIT_RESOURCE (Resource_File_Name)". لقد قمت بحل هذا بالرمز التالي (في كل ملف .cpp في مكتبة ثابتة):


#include <QAbstractButton>

namespace {
struct StaticLibInitializer
{
    StaticLibInitializer()
    {
        Q_INIT_RESOURCE(qtwidgets_custom_resources);
    }
};
StaticLibInitializer staticLibInitializer;
} 

// ... widget code ....

بدلاً من النهج الأول ، قمت بإنشاء ملف init.cpp منفصل في مشروع مكتبة ثابت مع رمز التهيئة (لتجنب تضمين رمز التهيئة في كل ملف .cpp) ، لكن هذا لم ينجح.

لماذا هذا لم ينجح؟

هل هذا النهج مع staticlibinitializer آمن ومحمول بين مختلف المجمعين والمنصات؟

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

المحلول

لم ينجح ذلك لأنك تمكنت من التعرض للضرب فشل التهيئة الثابتة.

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

StaticLibInitializer
{
    void initialize()
    {
        static Q_INIT_RESOURCE(qtwidgets_custom_resources);
    }

    StaticLibInitializer()
    {
         initialize();
    }
}

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

نصائح أخرى

لا يمكن استخدام ماكرو q_init_resource في مساحة الاسم.

اسمحوا لي أن أقتبس من دليل QT: "ملاحظة: لا يمكن استخدام هذا الماكرو في مساحة الاسم. يجب أن يسمى من Main ()". وحتى أنه يمنحك مثالًا على كيفية القيام بذلك بشكل صحيح ، إذا لم يكن ذلك ممكنًا:

  inline void initMyResource() { Q_INIT_RESOURCE(myapp); }

    namespace MyNamespace
    {
     ...

     void myFunction()
     {
         initMyResource();
     }
  }

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

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