覆盖对 main() 的调用

Override the call to main()?

本文关键字:调用 main 覆盖      更新时间:2023-10-16

我正在做一个项目,其中我们有几个共享多个目标文件的可执行文件。 我们希望将日志记录添加到所有可执行文件中,并为此提供一个库。

但是,转到每个可执行文件的main()函数并添加相同的样板函数调用来启动日志记录似乎很笨拙。 这意味着我们一遍又写同样的东西,并在可维护性和DRY("不要重复自己"(上松懈。 如果我们能够系统地确保在调用 main 函数之前开始日志记录,那就太好了。

我突然想到libc ++中有一些函数可以调用main,并且可以覆盖它们。 但是,我不知道它们是什么,并想象如果我们不小心,这可能会破坏事情。 有谁知道这将如何完成? 或者,如果这太过分了,关于如何进行的任何其他建议?

我们将 C++11 与 g++ 4.8 一起使用,如果它有任何区别的话。

您不需要通过修改main().来执行此操作

相反,您应该在共享对象库中的全局范围内创建一个类。这个类的构造函数将在 main(( 运行之前执行你想要做的"初始化",它的析构函数将在 main(( 之后运行。

您需要处理的问题是,对于任何其他全局范围对象,不能保证此初始化和销毁的顺序是确定性的。所有这些都可以放在一个.cpp编译单元中。

class LoggingManager // you can make this a singleton but not necessary
{
   public:
      LoggingManager(); 
      ~LoggingManager();
};
LoggingManager::LoggingManager()
{
     // your initialisation code goes here
}
LoggingManager::~LoggingManager()
{
     // your clean-up code goes here. It should not throw
}
LoggingManager loggingManagerStaticInstance; 

请注意,"静态初始化"问题存在一个小危险,这意味着实际上您的loggingManagerStaticInstance可能不会加载,直到首次访问编译单元。

实际上,只要初始化发生在第一次需要之前(有点像单例(,这是否在main()之后并不重要,但这意味着您的编译单元可能需要包含保证被拉入的内容。

如果你想"坚持"到 gnu 或类似的,他们提供了__attribute__(constructor)可能会解决它,尽管有一种更简单的方法可以实现一些虚拟的 extern int 或虚拟函数,该函数返回一个从您实际用于实现日志记录的任何标头中调用的 int。