【问题标题】:Linux equivalent of DllMainLinux 相当于 DllMain
【发布时间】:2012-09-09 22:22:50
【问题描述】:

在 *nix .so 库中,是否存在在加载和卸载库时由系统调用的入口点?

更实用的一点是:如果 .so 是用 C++ 编写的,并且它包含带有构造函数和析构函数的全局对象,并且它是从没有构造/析构概念的语言加载的,那么全局对象是否正确构造/析构?

【问题讨论】:

    标签: c++ shared-libraries shared-objects


    【解决方案1】:

    使用的技术略有不同,但 全局对象的构造/销毁或多或少内置于 动态加载器。 (即使在windows下也不需要经过 DllMain。全局对象将被正确构造/破坏 无论如何。)

    【讨论】:

      【解决方案2】:
      1. 不,没有等效于 DllMain。

      2. 对于 JNI 库,例如在 Android 上,可能有一个特殊的入口 JNI_OnLoad 用于填充 JNI 函数表。

      3. GCC 定义了特殊属性 constructor 以允许某些代码在共享库加载时运行。

      4. C++ 保证将执行全局和静态对象的构造函数,无论加载 .so 的代码是否知道这些类,或者有构造概念。

        同样适用于析构函数,但是当至少一些析构函数没有机会运行时,可能会出现不愉快的情况——例如当存在 sigfault 并禁用异常时。

      【讨论】:

      • 按照这个逻辑,每个构造函数都相当于 DllMain :)
      • 不完全是。 DllMain 为每个附加的线程运行 - 在 Linux 中没有任何类似的东西。而且,正如 James Kanze 所回答的,全局对象构造函数由运行时库运行,而不是通过 DllMain 机制。
      • 但是必须有操作系统级别的东西调用 RTL 的全局初始化序列...
      • @SevaAlekseyev:是的,但是 global-init 序列不必是可重载的,也不必在库中执行任何非构造函数(例如DllMain)。
      • @SevaAlekseyev:约定是__attribute__((constructor)) 的函数将在dlopen() 返回之前执行。
      【解决方案3】:

      您可以使用__attribute__((constructor))__attribute__((destructor)) 在共享库的加载和卸载时执行代码。

      【讨论】:

      • 来自 GNU GCC 手册:“但是,目前,具有静态存储持续时间的 C++ 对象的构造函数和使用属性构造函数修饰的函数的调用顺序是未指定的。”而 DllMain 保证在静态存储对象已经初始化时运行。如果您想使用库设置/拆卸函数中的静态对象,此保证很重要。
      • 您可以查看here 的区别。
      猜你喜欢
      • 2016-09-04
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      相关资源
      最近更新 更多