Russian Qt Forum
Октябрь 01, 2024, 20:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QFontDatabase app crash  (Прочитано 4726 раз)
Alp
Гость
« : Август 25, 2009, 19:35 »

Есть менеджер шрифтов, реализованный как синглтон Мейерса. В нем используется QFontDatabase что бы подгрузить шрифты с диска (точнее, из ресурсов), операция проходит успешно, вызов вида
id = QFontDatabase::addApplicationFont(":/fonts/MyriadPro-Bold.otf")
возвращает id загруженного шрифта, он != -1.

В деструкторе вызывается QFontDatabase::removeAllApplicationFonts(), и в нём приложение падает. Если этот вызов закомментировать - всё в порядке.
Помогите понять, в чем проблема.

Да, если вызов removeAllApplicationFonts переместить из в конструктор, сразу же после загрузки шрифтов - проблема исчезает, даже если вызов в деструкторе оставить.

Код
C++ (Qt)
#define SINGLETON_COPY_CREATE_RESTRICT(ClassName) \
                               ClassName() {}  \
                               ClassName(const ClassName&) {}  \
                               ClassName& operator=(const ClassName&) {return *(new ClassName());}   \
                               friend class Singleton <ClassName>;
 
#define SINGLETON_COPY_RESTRICT(ClassName)  ClassName(const ClassName&) {}  \
                                           ClassName& operator=(const ClassName&) {return *(new ClassName());}   \
                                           friend class Singleton <ClassName>;
 
template<class T> class Singleton   //Single-threaded Meyers singleton
{
protected:
   Singleton()                             {}
   Singleton(const Singleton&)             {}
   Singleton& operator=(const Singleton&)  {}
   virtual ~Singleton()                    {}
 
public:
   static T& Instance()
   {
       static T object;
       return object;
   }
};
 

Код
C++ (Qt)
class FontManager : public Singleton<FontManager>
{
   SINGLETON_COPY_RESTRICT(FontManager)
   FontManager();
public:
   ~FontManager();
 
};
 

Код
C++ (Qt)
FontManager::FontManager(void)
{
   int id = -1;
   id = QFontDatabase::addApplicationFont(":/fonts/MyriadPro-Bold.otf");
   id = QFontDatabase::addApplicationFont(":/fonts/MyriadPro-BoldCond.otf");
   id = QFontDatabase::addApplicationFont(":/fonts/MyriadPro-BoldIt.otf");
   id = QFontDatabase::addApplicationFont(":/fonts/MyriadPro-Cond.otf");
   id = QFontDatabase::addApplicationFont(":/fonts/MyriadPro-It.otf");
   id = QFontDatabase::addApplicationFont(":/fonts/MyriadPro-Regular.otf");
   id = QFontDatabase::addApplicationFont(":/fonts/MyriadPro-CondIt.otf");
}
 
FontManager::~FontManager()
{
   QFontDatabase::removeAllApplicationFonts();    //AARRRRRGHHHH!
}
 
 

« Последнее редактирование: Август 25, 2009, 19:37 от Alp » Записан
BRE
Гость
« Ответ #1 : Август 25, 2009, 20:30 »

Сейчас нет времени разбираться досконально, но есть предположение:
Вопрос в порядке вызова деструкторов для статических объектов. Возможно в момент вызова деструктора FontManager и соответственно метода QFontDatabase::removeAllApplicationFonts() внутренний структуры QFontDatabase уже разрушены.
То, что проблема исчезает если нет ни одного загруженного фонта, то это возможно из-за следующего кода в removeAllApplicationFonts():
Код
C++ (Qt)
   QMutexLocker locker(fontDatabaseMutex());
 
   QFontDatabasePrivate *db = privateDb();
   if (db->applicationFonts.isEmpty()) // !!! выходим без выгрузки фонтов
       return false;
 
   // Если фонты есть - думаю падает где-то здесь...
   FcConfigAppFontClear(0);
   db->applicationFonts.clear();
   db->invalidate(); // <<< Здесь очищается кэш фонтов (думаю здесь)
   return true;
 
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.112 секунд. Запросов: 20.