在模块加载/卸载时在外部 C++ 模块中构造/销毁对象

Posted

技术标签:

【中文标题】在模块加载/卸载时在外部 C++ 模块中构造/销毁对象【英文标题】:Constructing/destructing an object in external c++ module on module load/unload 【发布时间】:2012-08-19 15:34:03 【问题描述】:

我用 C++ 编写了一个 python 模块。一切正常,但现在我想添加日志记录。我的记录器类(第 3 方)需要类似于以下内容的初始化:

int main()

    Logger logger("log.log");
    Logger::Register(&logger);

    DoSomethingAndLog();
    return 0;

如您所见,logger 在程序初始化时创建,在程序终止时销毁。

我应该在哪里创建 Logger 对象,以便在加载模块时构建它并在卸载模块时销毁它?

【问题讨论】:

使用全局变量的明显方法怎么样?它们在 python 模块中的行为是否与通常的 DLL 或 EXE 不同? @Mikhail,我想它会起作用的。我希望有更优雅的解决方案。如果不是,则为全局。 @DeadMG, docs.python.org/extending/extending.html 【参考方案1】:

您可以将Logger 对象包装到一个类中并声明该类的全局实例。这种方法比原始的全局 Logger 变量有一点优势,因为您可以在构造函数和析构函数中控制初始化和取消初始化。您还可以限制对Logger 对象的访问。

class TheLogger

public:
  TheLogger()  Logger::Register(&_logger); 
  ~TheLogger()  Logger::Unregister(&_logger); 

  Logger& GetLogger()  return _logger; 

private:
  Logger _logger;
;

TheLogger theLogger;

int main()

  DoSomethingAndLog();

  theLogger.GetLogger().Log("...");

  return 0;

【讨论】:

这里有同样的问题。我在哪里构造和销毁theLogger?单例模式可以服务。但是,DoSomethingAndLog 按原样使用Logger。而且我不想更改此代码(很多) theLogger 是自动构造的,因为它是一个全局变量定义。几乎与在函数中本地声明它一样。 TheLogger 的构造函数在模块加载时被调用。 Logger 的定义没有改变,如果你的代码使用了Logger 的其他一些静态方法,什么都不会改变。 谢谢。 python 接口实际上提供了一种初始化函数,我可以在其中调用 Register 。我真的是在尝试避免全局定义并更好地控制破坏。

以上是关于在模块加载/卸载时在外部 C++ 模块中构造/销毁对象的主要内容,如果未能解决你的问题,请参考以下文章

在 Openmp (C++) 中销毁线程

全局范围的扩充只能直接嵌套在外部模块或环境模块声明中 (2669)

如何在外部模块中使用 Laravel 类?

在外部覆盖 python 模块函数

可以在外部模块上测试SPI通讯

Node.js:如何重新加载模块