你如何优先考虑全局构造函数?

Posted

技术标签:

【中文标题】你如何优先考虑全局构造函数?【英文标题】:How do you prioritize global constructors? 【发布时间】:2016-03-12 01:39:08 【问题描述】:

我有一个使用 Qt 的共享库版本 (5.2.0) 编写的程序,它显示的字体正常(大概是从 /usr/share/fonts 填充它的数据库)。 (不确定 Designer 文本是否来自与编程字体处理相同的数据库。)但后来我在开源静态版本(5.2.0)下重新编译它,字体变得丑陋。

我破坏了安装 Qt 的路径(因为静态版本的整个想法是独立于开发目录),果然它抱怨无法访问任何字体。所以我得出结论 Qt 改变了他们的静态版本,不再输入 /usr/share/fonts。互联网上的一些研究告诉我,他们改为查看...somedir/lib/fonts。

通过更多研究,我发现我可以使用 env var QT_QPA_FONTDIR 来设置搜索目录(尽管我怀疑它可能已简化为一级搜索,而不是递归)。不想编写脚本来包装程序并在调用它之前设置环境变量,我继续在程序中使用 putenv()。我选择了一个我认为会在 Qt 读取环境之前设置变量的地方,并且由于在 main() 之前调用了全局构造函数,并且肯定在实例化 QApplication 之前调用了它,所以我将它放在构造函数中。

但是,你猜怎么着,他们似乎在我的构造函数设置 QT_QPA_FONTDIR=/usr/share/fonts 之前读取了环境。

所以请帮忙!!!!如何让我的构造函数首先执行?

【问题讨论】:

可能的解决方案:***.com/questions/20751604/… Ryan,我希望将所有系统(Fedora 19)字体加载到 QFontDatabase 中。您提供的链接显示了如何将一种特定字体(在编译时已知的字体名称)嵌入到可执行文件中。所以这不是一个真正的解决方案。比如说,程序的目标是显示系统上所有可用的字体、字体名称和字体样式以及它们的外观。您必须获得所有字体,而不是特定字体。当程序在不同的机器上运行时,所有的字体,不一样的设置。不过感谢您的意见。 【参考方案1】:

一些编译器提供编译指示试图帮助你做这些事情,但简单的事实是 C++ 不保证模块之间的全局构造顺序。甚至不能保证一个对象依赖于另一个模块中的另一个对象将被第二次初始化。在这方面,全局变量是一个雷区。

如果您需要便携式解决方案,真的没有。

如果您可以保证您的编译器始终具有相同的风格,那么您可以使用编译指示、属性或链接顺序等技巧来解决该问题。例如,gcc 提供了一个名为 init_priority 的变量属性,但我不确定您是否可以使优先级高于默认值。

真的,换一种方式解决问题会更好。

【讨论】:

【参考方案2】:

谢谢艾肯鼓。链接顺序有效。我创建了最小的 .cpp,它使构造函数被全局实例化,调用 putenv() 来设置我的环境。我将它放在 .pro 文件的第一个位置,并检查它创建的 makefile 是否将它放在链接行的第一个位置。而且,嘿,快!! Qt 程序现在从正确的位置获取字体数据库。非常感谢。它是设置构造函数顺序的链接顺序(至少对于 GCC)。

【讨论】:

以上是关于你如何优先考虑全局构造函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何将@liaoliaots/nestjs-redis redis 连接传递给全局保护构造函数

析构函数与构造函数——对象的优先级问题

Java/优先级队列和构造函数和类型

python打印二叉树所有路径的主函数怎样写

全局对象的构造函数会在main 函数之前执行

Unity.Resolve 如何知道使用哪个构造函数?